7

这可能不是发布此内容的正确位置,但我不知道在哪里发布它。

我有 5 条线 (d1 -> d5) 在 3d 透视图中彼此平均分布,我有 (a) 角度、(d1) 和 (b5) 的值。我需要用 jquery 计算 (b2, b3, b4, d2, d3, d4, d5)。

在此处输入图像描述

我可以计算 d5:

d5 = d1 - ( b5 * Math.tan(a))

但我不知道如何计算 b2、b3 和 b4。(d1 分为 4 个相同的段)任何帮助将不胜感激。

4

2 回答 2

2

您正在寻找的是投影比例。在计算上做到这一点的最简单方法是使用齐次坐标,取一个矩形(如下面第一张图片中的那个),其中 V“向右无限远”,并找到一个投影变换,将该矩形映射到中的梯形第二张图片。矩形的顶点是(0|0)、(0|d1)、(b5|d1)、(b5|0),梯形对应的顶点是(0|0)、(0|d1)、( b5|d5), (b5|0)。

用于获得投影比例的投影变换的图示

由于这些是四个点,其中没有三个点是共线的,因此我们可以为这个变换找到一个唯一的矩阵(直到缩放)M。经过一些数学运算,结果证明这个矩阵是:

[d1*b5,0,0] 
[0,b5*d5,0]
[d1-d5,0,b5*d5]

例如,如果你想找到坐标 b3 和 d3,你可以将这个矩阵乘以直线中间点的齐次坐标,即向量 (0.5*b5,d1,1)^T,你得到点 (b3|d3) 的齐次坐标,可以通过去齐次化将其转换为欧几里得坐标,即将前两个分量除以第三个分量。

一般来说,如果你有两个点 (b1|d1) 和 (bn|dn),并且想知道在这样的投影尺度上的 n-2 个等距点的坐标,你可以像这样计算坐标 bi 和 di (在你的情况下,n 当然是 5):

let M := matrix [[d1*bn, 0, 0], [0, bn*dn, 0], [d1-dn, 0, bn*dn]]
let v := ((i-1)/(n-1)*bn, d1, 1)
let (x,y,z) := M*v
let bi := x/z and di := y/z

如您所见,这是一种用于计算这些投影等距点坐标的简单算法,并且可以很好地推广到任意数量的点。

如果您希望有一个封闭的公式,您可以直接计算 bi 和 di 为:

let bi := (bn*d1*(i-1))/(dn*n+(d1-dn)*i-d1)
let di := d1*dn*(n-1)/(dn*n+(d1-dn)*i-d1)
于 2013-03-08T04:39:35.977 回答
0

在此处输入图像描述

首先我们需要计算整个三角形d1 -> v -> c的相邻边的长度是多少(它的左侧垂直边):

tan(Θ) = opposite / adjacent
opposite * tan(Θ) = adjacent
adjacent = opposite * tan(Θ)
adjacent = d1 * tan(a)

接下来我们需要知道从v到线d1的每条线离地面有多少。假设变量s对于所有分割都是相同的,并假设N个分割段(在本例中为 3),我们的计数器是i,它从 1 开始到N

opposite(i) = i * (d1 / N)

现在我们需要从v到每个标记s 的线所形成的角度:

tan(Θi) = opposite / adjacent
Θi = arctan(opposite / adjacent)
Θi = arctan(opposite(i) / adjacent)
Θi = arctan((i * (d1 / N)) / (d1 * tan(a)))

使用一些几何/三角函数,我们可以说从d1通过点cd5顶部的角度是 (90° - a)。我们称这个角为a'

a' = 90° - a

正弦定律告诉我们:

A' / sin(a') = opposite(i) / sin(b')

所以现在我们求解 A' 因为我们需要一些帮助来获取橙色正方形的尺寸:

A' = (opposite(i) * sin (a')) / sin(b')

因为b' = ( a + Θi ) 这变成:

A' = (opposite(i) * sin (90° - a)) / sin(a + Θi)

应用相同的方法,但求解橙色三角形中的h(见图):

h / sin(90°-Θi) = A' / sin(90°)
h = (A' * sin(90°-Θi)) / sin(90°)    
b2 = h

把它们放在一起(希望我没有复制/粘贴错误)并且没有简化:

b2 = (((( i * (d1 / N)) * sin (90° - a)) / sin(a + Θi)) * sin(90° - arctan((i * (d1 / N)) / (d1 * tan(a))))) / sin(90°)    

现在冲洗/重复i的每个值并变成代码(我会这样做但我太累了):)

于 2013-03-08T04:34:21.853 回答