- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试绘制 2 个单位向量,然后在它们之间绘制一条弧线。我不是在寻找任何解决方案,而是想知道为什么我的特定解决方案不起作用。
首先,我随机选择 2 个单位向量。
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return Math.random() * (max - min) + min;
}
var points = [{},{}];
points[0].direction = normalize([rand(-1, 1), rand(-1, 1), 0]);
points[1].direction = normalize([rand(-1, 1), rand(-1, 1), 0]);
注意:这里的数学是 3D 的,但我通过将向量保持在 XY 平面中来使用 2d 示例
我可以在 Canvas 中绘制这 2 个单位向量
// move to center of canvas
var scale = ctx.canvas.width / 2 * 0.9;
ctx.transform(ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.scale(scale, scale); // expand the unit fill the canvas
// draw a line for each unit vector
points.forEach(function(point) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(point.direction[0], point.direction[1]);
ctx.strokeStyle = point.color;
ctx.stroke();
});
有效。
接下来我想制作一个矩阵,将 XY 平面的 Y 轴与第一个单位向量对齐,并与 2 个单位向量所描述的平面处于同一平面
var zAxis = normalize(cross(points[0].direction, points[1].direction));
var xAxis = normalize(cross(zAxis, points[0].direction));
var yAxis = points[0].direction;
然后我使用该矩阵绘制一个单位网格
ctx.setTransform(
xAxis[0] * scale, xAxis[1] * scale,
yAxis[0] * scale, yAxis[1] * scale,
ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.beginPath();
for (var y = 0; y < 20; ++y) {
var v0 = (y + 0) / 20;
var v1 = (y + 1) / 20;
for (var x = 0; x < 20; ++x) {
var u0 = (x + 0) / 20;
var u1 = (x + 1) / 20;
ctx.moveTo(u0, v0);
ctx.lineTo(u1, v0);
ctx.moveTo(u0, v0);
ctx.lineTo(u0, v1);
}
}
ctx.stroke();
这也行。运行下面的示例,可以看到粉红色单位网格始终与绿色单位向量对齐并面向红色单位向量的方向。
最后使用单位网格的数据,我想将其弯曲正确的量以填充 2 个单位向量之间的空间。鉴于它是一个单位网格,我似乎应该能够做到这一点
var cosineOfAngleBetween = dot(points[0].direction, points[1].direction);
var expand = (1 + -cosineOfAngleBetween) / 2 * Math.PI;
var angle = x * expand; // x goes from 0 to 1
var newX = sin(angle) * y; // y goes from 0 to 1
var newY = cos(angle) * y;
如果我为每个网格点绘制 newX
和 newY
,我似乎应该得到 2 个单位向量之间的正确弧线。
取两个单位向量的点积应该得到它们之间夹 Angular 的余弦值,如果它们重合,则从1
到-1
,如果它们重合对面的。在我的例子中,我需要 expand
从 0
到 PI
所以 (1 + -dot(p0, p1))/2 * PI
似乎应该可以工作。
但事实并非如此。请看蓝色圆弧,它是上面代码的输入单位网格点。
我检查了一些东西。我检查过 zAxis
是否正确。它总是 [0,0,1]
或 [0,0,-1]
是正确的。我检查了 xAxis
和 yAxis
是单位向量。他们是。我检查了将 expand
手动设置为 PI * .5
、PI
、PI * 2
,它完全符合我的要求预计。 PI * .5
得到一个 90 度的弧,从蓝色单位向量开始的 1/4 处。 PI
完全符合我的预期得到一个半圆。 PI * 2
得到一个完整的圆。
这使得 dot(p0,p1)
看起来是错误的,但查看 dot
函数似乎是正确的,如果用各种简单的向量测试它,它会返回什么我希望 dot([1,0,0], [1,0,0])
返回 1。dot([-1,0,0],[1,0,0 ])
返回 -1。 dot([1,0,0],[0,1,0])
返回 0。dot([1,0,0],normalize([1,1,0] ))
返回 0.707...
我错过了什么?
下面是代码
function cross(a, b) {
var dst = []
dst[0] = a[1] * b[2] - a[2] * b[1];
dst[1] = a[2] * b[0] - a[0] * b[2];
dst[2] = a[0] * b[1] - a[1] * b[0];
return dst;
}
function normalize(a) {
var dst = [];
var lenSq = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
var len = Math.sqrt(lenSq);
if (len > 0.00001) {
dst[0] = a[0] / len;
dst[1] = a[1] / len;
dst[2] = a[2] / len;
} else {
dst[0] = 0;
dst[1] = 0;
dst[2] = 0;
}
return dst;
}
function dot(a, b) {
return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
}
var canvas = document.querySelector("canvas");
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext("2d");
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return Math.random() * (max - min) + min;
}
var points = [
{
direction: [0,0,0],
color: "green",
},
{
direction: [0,0,0],
color: "red",
},
];
var expand = 1;
var scale = ctx.canvas.width / 2 * 0.8;
function pickPoints() {
points[0].direction = normalize([rand(-1, 1), rand(-1, 1), 0]);
points[1].direction = normalize([rand(-1, 1), rand(-1, 1), 0]);
expand = (1 + -dot(points[0].direction, points[1].direction)) / 2 * Math.PI;
console.log("expand:", expand);
render();
}
pickPoints();
function render() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.save();
ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.scale(scale, scale);
ctx.lineWidth = 3 / scale;
points.forEach(function(point) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(point.direction[0], point.direction[1]);
ctx.strokeStyle = point.color;
ctx.stroke();
});
var zAxis = normalize(cross(points[0].direction, points[1].direction));
var xAxis = normalize(cross(zAxis, points[0].direction));
var yAxis = points[0].direction;
ctx.setTransform(
xAxis[0] * scale, xAxis[1] * scale,
yAxis[0] * scale, yAxis[1] * scale,
ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.lineWidth = 0.5 / scale;
ctx.strokeStyle = "pink";
drawPatch(false);
ctx.strokeStyle = "blue";
drawPatch(true);
function drawPatch(curved) {
ctx.beginPath();
for (var y = 0; y < 20; ++y) {
var v0 = (y + 0) / 20;
var v1 = (y + 1) / 20;
for (var x = 0; x < 20; ++x) {
var u0 = (x + 0) / 20;
var u1 = (x + 1) / 20;
if (curved) {
var a0 = u0 * expand;
var x0 = Math.sin(a0) * v0;
var y0 = Math.cos(a0) * v0;
var a1 = u1 * expand;
var x1 = Math.sin(a1) * v0;
var y1 = Math.cos(a1) * v0;
var a2 = u0 * expand;
var x2 = Math.sin(a0) * v1;
var y2 = Math.cos(a0) * v1;
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.moveTo(x0, y0);
ctx.lineTo(x2, y2);
} else {
ctx.moveTo(u0, v0);
ctx.lineTo(u1, v0);
ctx.moveTo(u0, v0);
ctx.lineTo(u0, v1);
}
}
}
ctx.stroke();
}
ctx.restore();
}
window.addEventListener('click', pickPoints);
canvas {
border: 1px solid black;
}
div {
display: flex;
}
<div><canvas></canvas><p> Click for new points</p></div>
最佳答案
您的dot
乘积函数没有问题。这就是您使用它的方式:
expand = (1 + -dot(points[0].direction, points[1].direction)) / 2 * Math.PI;
应该是:
expand = Math.acos(dot(points[0].direction, points[1].direction));
您使用的 expand
变量是一个 Angular (以弧度表示)。 dot
乘积为您提供 Angular 余弦值,但不是 Angular 本身。虽然输入 [0,pi] 的 Angular 余弦值在 1 和 -1 之间变化,但该值不会线性映射回 Angular 本身。
换句话说,它不起作用,因为 Angular 余弦不能简单地通过缩放来转换为 Angular 本身。这就是反正弦的用途。
请注意,一般来说,如果您只需要一个近似值,通常可以使用原始公式(或将 [-1,1] 域映射到 [0,pi] 范围的任何简单公式),但它永远不会给出一个精确的 Angular ,除非在极端情况下。
这可以通过 plotting the two functions on top of each other 直观地看到:
关于javascript - 如何在 2 个单位向量之间弯曲单位网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35728518/
我正在使用我的简单 PHP 验证码算法 ( http://www.source.ofitall.com/devel/captcha.php ),我一直在努力尝试调整它以使其更具吸引力和更易于阅读,谷歌
我正在 android 中实现一个 ListView ,它看起来就像这样并滚动 我一直在通过在我的适配器的 getView 中设置膨胀行的布局参数来做到这一点,但由此引发的问题是 ListView 变
我正在尝试使用 flex 和 bison 创建一个计算器,它可以进行一组操作(结果分配给变量)。计算器使用存储器来存储这些变量。当我通过终端(标准输入键盘)进行此计算时,一切正常。但是,当我尝试使用文
我的Flex应用程序中有数据网格,我使用Arraycollection绑定(bind)数据网格(使用remoteobject方法调用从java类获取数据)。现在我正在数据网格中执行添加/编辑/删除,我
是否可以制作弯曲或拱形形状的矩形。这是我的 jsfiddle https://jsfiddle.net/dibyendu/y8pthz2x/ 。我想使用 d3 使雷达图轴上的这些矩形成为弧形/曲线 最
我有一张代表某个区域海拔的图像。但是制造它的无人机不一定走直线(尽管图像总是矩形的)。我还有每 20 厘米生成的 gps 坐标。 如何“弯曲”这个矩形图像(曲线/马赛克),使其代表无人机实际经过的弯曲
我经历了How to curve the top of a UIView Controller in Swift 并发表看法。它附在下面。我想从我的 View 中删除该背景色。我在 Storyboar
任何人都可以帮助弯曲 View 以达到以下效果。我正在使用自定义 View 组,我想操纵 Canvas 来实现以下效果,谁能帮帮我。 谢谢 最佳答案 你需要知道: Camera Matrix 这是一个
我尝试绘制一些 3D 正方形(在 iPhone 上使用 OpenGL)并让它们旋转,现在它们看起来像一个球体。 http://i618.photobucket.com/albums/tt265/Loy
我想创建一个 div,它是一个按钮,它包含一个国旗的图片和一个国家的 abv,我已经将一些代码放入我想要的内容中,但这不是 Bootstrap 的方式,我'我正在努力解决这个问题,以及如何使用 boo
现在我正在用一系列 View 填充 UIScrollView。需要扭曲 View 以使 UIScrollView 看起来像旋转木马。换句话说,当用户滚动时,它需要像一个圆圈。我以前从未做过类似的事情,
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一名优秀的程序员,十分优秀!