空间曲线的参数方程
二维直线
经过一点
P
(
x
0
,
y
0
)
P(x_0,y_0)
P(x0,y0)的方向向量为
n
(
c
o
s
θ
,
s
i
n
θ
)
n(cos\theta,sin\theta)
n(cosθ,sinθ)的直线参数方程为:
[
x
y
]
=
[
x
0
y
0
]
+
t
[
c
o
s
θ
s
i
n
θ
]
t
∈
[
0
,
2
π
)
\begin{bmatrix} x\\ y \end{bmatrix} =\begin{bmatrix} x_0\\ y_0 \end{bmatrix} +t\begin{bmatrix} cos\theta\\ sin\theta \end{bmatrix} \hspace{2em} t\in [0,2\pi)
[xy]=[x0y0]+t[cosθsinθ]t∈[0,2π)
三维直线
经过一点
P
(
x
0
,
y
0
,
z
0
)
P(x_0,y_0,z_0)
P(x0,y0,z0)的单位方向向量为
n
(
i
,
j
,
k
)
n(i,j,k)
n(i,j,k)的直线参数方程为:
[
x
y
z
]
=
[
x
0
y
0
z
0
]
+
t
[
i
j
k
]
t
∈
[
0
,
2
π
)
\begin{bmatrix} x\\ y\\ z \end{bmatrix} =\begin{bmatrix} x_0\\ y_0\\ z_0 \end{bmatrix} +t\begin{bmatrix} i\\ j\\ k \end{bmatrix} \hspace{2em} t\in [0,2\pi)
xyz
=
x0y0z0
+t
ijk
t∈[0,2π)
二维圆
经过圆心 P ( x 0 , y 0 ) P(x_0,y_0) P(x0,y0),半径为 r r r,的圆参数方程为:
[ x y ] = [ x 0 y 0 ] + r [ c o s θ s i n θ ] θ ∈ [ 0 , 2 π ) \begin{bmatrix} x\\ y \end{bmatrix} =\begin{bmatrix} x_0\\ y_0 \end{bmatrix} +r\begin{bmatrix} cos\theta\\ sin\theta \end{bmatrix} \hspace{2em} \theta\in [0,2\pi) [xy]=[x0y0]+r[cosθsinθ]θ∈[0,2π)
三维圆
经过圆心 P ( x 0 , y 0 , z 0 ) P(x_0,y_0,z_0) P(x0,y0,z0),半径为 r r r,且该圆所在的平面正交的两个单位向量 e 1 ⃗ ( a x , a y , a z ) , e 2 ⃗ ( b x , b y , b z ) \vec{e_1}(a_x,a_y,a_z),\vec{e_2}(b_x,b_y,b_z) e1(ax,ay,az),e2(bx,by,bz)的圆参数方程为:
[ x y z ] = [ x 0 y 0 z 0 ] + r c o s θ [ a x a y a z ] + r s i n θ [ b x b y b z ] θ ∈ [ 0 , 2 π ) \begin{bmatrix} x\\ y\\ z \end{bmatrix}= \begin{bmatrix} x_0\\ y_0\\ z_0 \end{bmatrix} +rcos\theta\begin{bmatrix} a_x\\ a_y\\ a_z \end{bmatrix} +rsin\theta\begin{bmatrix} b_x\\ b_y\\ b_z \end{bmatrix} \hspace{2em} \theta\in [0,2\pi) xyz = x0y0z0 +rcosθ axayaz +rsinθ bxbybz θ∈[0,2π)
特殊情况下,当 e 1 ⃗ ( a x , a y , a z ) , e 2 ⃗ ( b x , b y , b z ) \vec{e_1}(a_x,a_y,a_z),\vec{e_2}(b_x,b_y,b_z) e1(ax,ay,az),e2(bx,by,bz)分别为 e 1 ⃗ ( 1 , 0 , 0 ) , e 2 ⃗ ( 0 , 1 , 0 ) \vec{e_1}(1,0,0),\vec{e_2}(0,1,0) e1(1,0,0),e2(0,1,0)时,公式(4) 简化为:
[ x y z ] = [ x 0 y 0 z 0 ] + r [ c o s θ s i n θ 0 ] θ ∈ [ 0 , 2 π ) \begin{bmatrix} x\\ y\\ z \end{bmatrix} =\begin{bmatrix} x_0\\ y_0\\ z_0 \end{bmatrix} +r\begin{bmatrix} cos \theta \\ sin \theta \\ 0 \end{bmatrix} \hspace{2em} \theta \in [0,2 \pi) xyz = x0y0z0 +r cosθsinθ0 θ∈[0,2π)
任意平面内的圆,可以先计算基准坐标系中的圆然后通过坐标变换 ,将问题转化为,转换为所求平面内的圆。
图形化表示:
如何快速求解 e 1 ⃗ ( a x , a y , a z ) , e 2 ⃗ ( b x , b y , b z ) \vec{e_1}(a_x,a_y,a_z),\vec{e_2}(b_x,b_y,b_z) e1(ax,ay,az),e2(bx,by,bz)?
- 求解 e 1 ⃗ \vec{e_1} e1,将圆所在平面的法向量与坐标向量 i ⃗ \vec{i} i叉乘,然后单位化即可得到,如果叉乘结果为0 ,就叉乘 j ⃗ \vec{j} j,再者就叉乘 k ⃗ \vec{k} k;
- 求解 e 2 ⃗ \vec{e_2} e2,就将法向量与 e 1 ⃗ \vec{e_1} e1叉乘即可。
对应的python代码:
\sum_{s}^{} {\textstyle \sum_{}^{}} # 对应的版本matplotlib 3.7.1 py311h06a4308_1
from matplotlib import pyplot as plt
import numpy as np
normal_direction = np.array([1, 1, 1])
radius = 1
center = np.array([1, 1, 1])
pi = 3.1415926
theta = np.array([])
for i in range(100):
theta = np.append(theta, 2.0 * pi * i / 100)
theta = np.array(theta)
e1 = np.cross(normal_direction, [0, 1, 0])
if np.linalg.norm(e1) < 1e-10:
e1 = np.cross(normal_direction, [0, 1, 0])
e2 = np.cross(normal_direction, e1)
# 单位化
e1_norm = e1 / np.linalg.norm(e1)
e2_norm = e2 / np.linalg.norm(e2)
size = np.size(theta)
x0 = center[0] * np.ones(size)
y0 = center[1] * np.ones(size)
z0 = center[2] * np.ones(size)
x = x0 + radius * e1[0] * np.cos(theta) + radius * e2[0] * np.sin(theta)
y = y0 + radius * e1[1] * np.cos(theta) + radius * e2[1] * np.sin(theta)
z = z0 + radius * e1[2] * np.cos(theta) + radius * e2[2] * np.sin(theta)
# 建立画布
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim(-2, 6)
ax.set_ylim(-2, 6)
ax.set_zlim(-2, 6)
ax.plot3D(x, y, z, 'r')
plt.show()
print("YES PF!")
对应的MATLAB代码
Figure_1normal=[1 1 1]; %法向量n
radius=1; %圆的半径为1
center=[1 1 1]; %圆心的坐标
theta=(0:2*pi/100:2*pi)'; %theta角从0到2*pi
e1=cross(normal,[1 0 0]); %n与i叉乘,求取a向量
if ~any(e1) %如果a为零向量,将n与j叉乘
e1=cross(normal,[0 1 0]);
end
e2=cross(normal,e1); %求取b向量
e1=e1/norm(e1); %单位化a向量
e2=e2/norm(e2); %单位化b向量
x0=center(1)*ones(size(theta,1),1);
y0=center(2)*ones(size(theta,1),1);
z0=center(3)*ones(size(theta,1),1);
x=x0+radius*e1(1)*cos(theta)+radius*e2(1)*sin(theta);%圆上各点的x坐标
y=y0+radius*e1(2)*cos(theta)+radius*e2(2)*sin(theta);%圆上各点的y坐标
z=z0+radius*e1(3)*cos(theta)+radius*e2(3)*sin(theta);%圆上各点的z坐标
plot3(x,y,z)
xlabel('x轴')
ylabel('y轴')
zlabel('z轴')
三维椭圆
在实际工程化的应用的时候,往往不是圆,而是退化成椭圆,甚至退化成一条直线。
工程中更多是使用椭圆模型,通过检测到的点来确定椭圆的参数,最后确定椭圆的中心点和方向向量。
三维椭圆的参数方程易知:
[
x
y
z
]
=
[
x
0
y
0
z
0
]
+
a
c
o
s
θ
[
a
x
a
y
a
z
]
+
b
s
i
n
θ
[
b
x
b
y
b
z
]
θ
∈
[
0
,
2
π
)
\begin{bmatrix} x\\ y\\ z \end{bmatrix} =\begin{bmatrix} x_0\\ y_0\\ z_0 \end{bmatrix} +acos\theta\begin{bmatrix} a_x\\ a_y\\ a_z \end{bmatrix} + bsin\theta\begin{bmatrix} b_x\\ b_y\\ b_z \end{bmatrix} \hspace{2em} \theta\in [0,2\pi)
xyz
=
x0y0z0
+acosθ
axayaz
+bsinθ
bxbybz
θ∈[0,2π)
其中
a
,
b
a,b
a,b分别表示为椭圆的长半轴长度,短半轴长度 。其余跟圆类似不作具体说明。
椭圆一般化方程为:
c
1
x
2
+
c
2
x
y
+
c
3
y
2
+
c
4
x
+
c
5
y
+
c
6
=
0
c_1x^2+c_2xy+c_3y^2+c_4x+c_5y+c_6 = 0
c1x2+c2xy+c3y2+c4x+c5y+c6=0
可以看到至少使用五个不同点可以确定这六个参数。
一般情况是点的个数远超过5个,处理步骤为:
-
首先使用RANSAC筛选异常点
-
构建误差 d i = c 1 x 2 + c 2 x y + c 3 y 2 + c 4 x + c 5 y + c 6 d_i = c_1x^2+c_2xy+c_3y^2+c_4x+c_5y+c_6 di=c1x2+c2xy+c3y2+c4x+c5y+c6
-
构建代价函数,使用最小二乘求解// 或者SVD分解
c i = a r g m i n Σ d j 2 s , t { ∑ i = 1 6 c i 2 = 1 i ∈ [ 1 , 6 ] , j ∈ [ 1 , n ] {c_i} = argmin\Sigma d_j^2 \hspace{2em} s,t \left\{\begin{matrix} \hspace{1em} \sum_{i=1}^{6}c_i^2 = 1 \\ \hspace{1em} i\in[1,6], \\ \hspace{1em}j\in [1,n] \end{matrix}\right. ci=argminΣdj2s,t⎩ ⎨ ⎧∑i=16ci2=1i∈[1,6],j∈[1,n] -
假设获得 c i c_i ci ,求解对应的圆心和法向量
使用二次型构造,对称矩阵,进行分解,则特征值满足:
λ 1 ≥ λ 2 > 0 > λ 3 \lambda_1 \ge\lambda_2>0>\lambda_3 λ1≥λ2>0>λ3
如果不满足,改变构造的对称矩阵的符号,重新求解对特征值这里直接给出结论:
H H H为分解矩阵后的特征向量组成的正交矩阵,法向量 n ⃗ \vec{n} n,和中心点 P P P为:
c o s 2 φ = λ 2 − λ 3 λ 1 − λ 3 n ⃗ = ± H [ − s i n φ 0 c o s φ ] P = ± H [ − λ 3 / λ 1 s i n φ 0 − λ 1 / λ 3 c o s φ ] cos^2\varphi = \frac{\lambda_2-\lambda_3}{\lambda_1-\lambda_3} \\ \\ \vec{n} = \pm H\begin{bmatrix} -sin\varphi \\ 0 \\ cos\varphi \end{bmatrix} \\ \\ P=\pm H \begin{bmatrix} -\sqrt{\lambda_3/\lambda_1}sin\varphi \\ 0 \\ \sqrt{-\lambda_1/\lambda_3}cos\varphi \end{bmatrix} cos2φ=λ1−λ3λ2−λ3n=±H −sinφ0cosφ P=±H −λ3/λ1sinφ0−λ1/λ3cosφ
参考链接: