用 3D 对数螺旋连接两个点 (Julia)

Connecting two points with a 3D logarithmic spiral (Julia)

提问人:AaronJPung 提问时间:7/22/2022 更新时间:7/22/2022 访问量:171

问:

我正在沿着两点之间的三维对数螺旋计算点。我似乎很接近,但我认为我在某处错过了一个条件符号翻转。

此代码工作得相对较好:

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"))

并生成以下图。端点的值显示在图上,并带有从坐标到其相应标记的箭头。第一点是关闭的,但它足够接近我的喜好。enter image description here

当我翻转时,问题就来了,这样p2p1

p1 = [3,10,2]
p2 = [1,1,1]

在这种情况下,我仍然得到一个从 到 的螺旋,并且终点 () 非常准确。但是,另一个端点 () 完全偏离:p2p1p1p2enter image description here

我认为这是由于我改变了两点的相对Z位置,但我不确定,而且我无法解开这个谜语。任何帮助将不胜感激。(如果您能帮助弄清楚为什么在第一个示例中 Z 值处于关闭状态,那就加分!p2

数学 Julia 对数 螺旋

评论

0赞 7/22/2022
您的螺旋线未完全指定。中心应该在哪里?轴是垂直的吗?t 和 z 之间有什么关系?请注意,中心不是 t=0 的点。

答:

1赞 Amon 7/22/2022 #1

假设这是您的另一个问题的后续:在 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)
0赞 user1196549 7/22/2022 #2

在二维中,我们假设点处的极点和 从 到 的螺旋线,对应于区间中参数的变化。CPQ[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)

从前两个,通过笛卡尔到极变换(和对数),您可以得到 和 。从最后两个,您同样得到 和 ,现在定义了螺旋。bda+bc+d

对于 Z 坐标,我无法准确回答,因为您没有描述如何将螺旋推广到 3D。无论如何,我们可以假设一个 ,您可以通过线性变换映射到该函数Z(t)[Pz, Qz]

(Qz - Pz) . (Z(t) - Z(0)) / (Z(1) - Z(0)) + Pz.