提问人:AaronJPung 提问时间:7/22/2022 更新时间:7/22/2022 访问量:171
用 3D 对数螺旋连接两个点 (Julia)
Connecting two points with a 3D logarithmic spiral (Julia)
问:
我正在沿着两点之间的三维对数螺旋计算点。我似乎很接近,但我认为我在某处错过了一个条件符号翻转。
此代码工作得相对较好:
using PlotlyJS
using LinearAlgebra
# Points to connect (`p2` spirals into `p1`)
p1 = [1,1,1]
p2 = [3,10,2]
# Number of curve revolutions
rev = 3
# Number of points defining the curve
rez = 500 # Number of points defining the line
r = norm(p1-p2)
t = range(0,r,rez)
theta_offset = atan((p1[2]-p2[2])/(p1[1]-p2[1]))
theta = range(0, 2*pi*rev, rez) .+ theta_offset
x = cos.(theta).*exp.(-t).*r.+p1[1];
y = sin.(theta).*exp.(-t).*r.+p1[2];
z = exp.(-t).*log.(r).+p1[3]
# Plot curve points
plot(scatter(x=x, y=y, z=z, marker=attr(size=2,color="red"),type="scatter3d"))
并生成以下图。端点的值显示在图上,并带有从坐标到其相应标记的箭头。第一点是关闭的,但它足够接近我的喜好。
当我翻转时,问题就来了,这样p2
p1
p1 = [3,10,2]
p2 = [1,1,1]
在这种情况下,我仍然得到一个从 到 的螺旋,并且终点 () 非常准确。但是,另一个端点 () 完全偏离:p2
p1
p1
p2
我认为这是由于我改变了两点的相对Z位置,但我不确定,而且我无法解开这个谜语。任何帮助将不胜感激。(如果您能帮助弄清楚为什么在第一个示例中 Z 值处于关闭状态,那就加分!p2
答:
假设这是您的另一个问题的后续:在 Julia 中的两个已知点之间绘制一个等角螺旋
我假设您只想使用圆柱坐标系为之前的 2D 问题添加第三个维度。这意味着您需要将一侧的 x 和 y 坐标的处理分开,将另一侧的 z 坐标分开。
首先,您需要计算前两个坐标:r
r = norm(p1[1:2]-p2[1:2])
然后,在计算 z 时,您只需要在公式中取第三个维度(不确定为什么您首先在那里使用函数):log
z = exp.(-t).*(p1[3]-p2[3]).+p2[3]
这将修复您的 z 轴。
最后,对于 x 和 y 坐标,请使用 two 参数函数:atan
julia>?atan
help?> atan
atan(y)
atan(y, x)
Compute the inverse tangent of y or y/x, respectively.
For one argument, this is the angle in radians between the positive x-axis and the point (1, y), returning a value in the interval [-\pi/2, \pi/2].
For two arguments, this is the angle in radians between the positive x-axis and the point (x, y), returning a value in the interval [-\pi, \pi]. This corresponds to a standard atan2
(https://en.wikipedia.org/wiki/Atan2) function. Note that by convention atan(0.0,x) is defined as \pi and atan(-0.0,x) is defined as -\pi when x < 0.
喜欢这个:
theta_offset = atan( p1[2]-p2[2], p1[1]-p2[1] )
最后,就像你上一个问题一样,在 x、y 和 z 的末尾添加 p2 点而不是 p1 点:
x = cos.(theta).*exp.(-t).*r.+p2[1];
y = sin.(theta).*exp.(-t).*r.+p2[2];
z = exp.(-t).*(p1[3]-p2[3]).+p2[3]
最后,我有这个:
using PlotlyJS
using LinearAlgebra
# Points to connect (`p2` spirals into `p1`)
p2 = [1,1,1]
p1 = [3,10,2]
# Number of curve revolutions
rev = 3
# Number of points defining the curve
rez = 500 # Number of points defining the line
r = norm(p1[1:2]-p2[1:2])
t = range(0.,norm(p1-p2), length=rez)
theta_offset = atan( p1[2]-p2[2], p1[1]-p2[1] )
theta = range(0., 2*pi*rev, length=rez) .+ theta_offset
x = cos.(theta).*exp.(-t).*r.+p2[1];
y = sin.(theta).*exp.(-t).*r.+p2[2];
z = exp.(-t).*(p1[3]-p2[3]).+p2[3]
@show (x[begin], y[begin], z[begin])
@show (x[end], y[end], z[end]);
# Plot curve points
plot(scatter(x=x, y=y, z=z, marker=attr(size=2,color="red"),type="scatter3d"))
这给出了预期的结果:
p2 = [1,1,1]
p1 = [3,10,2]
(x[begin], y[begin], z[begin]) = (3.0, 10.0, 2.0)
(x[end], y[end], z[end]) = (1.0001877364735474, 1.0008448141309634, 1.0000938682367737)
和:
p1 = [1,1,1]
p2 = [3,10,2]
(x[begin], y[begin], z[begin]) = (0.9999999999999987, 1.0, 1.0)
(x[end], y[end], z[end]) = (2.9998122635264526, 9.999155185869036, 1.9999061317632263)
在二维中,我们假设点处的极点和 从 到 的螺旋线,对应于区间中参数的变化。C
P
Q
[0, 1]
我们有
X = Cx + cos(at+b).e^(ct+d)
Y = Cy + sin(at+b).e^(ct+d)
使用已知点,
Px - Cx = cos(b).e^d
Py - Cy = sin(b).e^d
Qx - Cx = cos(a+b).e^(c+d)
Qy - Cy = sin(a+b).e^(c+d)
从前两个,通过笛卡尔到极变换(和对数),您可以得到 和 。从最后两个,您同样得到 和 ,现在定义了螺旋。b
d
a+b
c+d
对于 Z 坐标,我无法准确回答,因为您没有描述如何将螺旋推广到 3D。无论如何,我们可以假设一个 ,您可以通过线性变换映射到该函数Z(t)
[Pz, Qz]
(Qz - Pz) . (Z(t) - Z(0)) / (Z(1) - Z(0)) + Pz.
上一个:如何在python中做字母螺旋?
下一个:螺旋矩阵 java
评论