Math 在三维空间中绘制与线向量垂直的点

Math 在三维空间中绘制与线向量垂直的点,math,geometry,language-agnostic,trigonometry,Math,Geometry,Language Agnostic,Trigonometry,我试图计算三维空间中与线向量正交/垂直的点 我有P1和P2,它们构成了这条线。然后我试图找到一个半径以P1为中心的点,它与直线正交 我想用三角函数来做这件事,不需要任何编程语言特定的函数 目前,我正在测试这个函数的精确度,方法是在线向量周围画一个圆 我还旋转三维空间中的线向量,以查看绘制的圆发生了什么,这就是我的结果变化的地方 一些不必要的影响包括: 旋转并通过线向量的圆。 随着线向量方向的改变,圆的半径在增大之前似乎减小到零 我曾经让我开始,并从那时起对代码进行了一些调整 如果有任何帮助,我将

我试图计算三维空间中与线向量正交/垂直的点

我有P1和P2,它们构成了这条线。然后我试图找到一个半径以P1为中心的点,它与直线正交

我想用三角函数来做这件事,不需要任何编程语言特定的函数

目前,我正在测试这个函数的精确度,方法是在线向量周围画一个圆

我还旋转三维空间中的线向量,以查看绘制的圆发生了什么,这就是我的结果变化的地方

一些不必要的影响包括: 旋转并通过线向量的圆。 随着线向量方向的改变,圆的半径在增大之前似乎减小到零

我曾经让我开始,并从那时起对代码进行了一些调整

如果有任何帮助,我将不胜感激——我已经花了3天的时间画圆圈了。这是到目前为止我的代码

//Define points which form the line vector
dx = p2x - p1x;
dy = p2y - p1y;
dz = p2z - p1z;

// Normalize line vector
d = sqrt(dx*dx + dy*dy + dz*dz);

// Line vector
v3x = dx/d;
v3y = dy/d;
v3z = dz/d;

// Angle and distance to plot point around line vector
angle = 123 * pi/180 //convert to radians
radius = 4;

// Begin calculating point
s = sqrt(v3x*v3x + v3y*v3y + v3z*v3z);

// Calculate v1.
// I have been playing with these variables (v1x, v1y, v1z) to try out different configurations.
v1x = s * v3x;
v1y = s * v3y;
v1z = s * -v3z;

// Calculate v2 as cross product of v3 and v1.
v2x = v3y*v1z - v3z*v1y;
v2y = v3z*v1x - v3x*v1z;
v2z = v3x*v1y - v3y*v1x;

// Point in space around the line vector
px = p1x + (radius * (v1x * cos(angle)) + (v2x * sin(angle)));
py = p1y + (radius * (v1y * cos(angle)) + (v2y * sin(angle)));
pz = p1z + (radius * (v1z * cos(angle)) + (v2z * sin(angle)));
编辑

在禁闭期间与此搏斗了几天之后,我终于设法让它工作了。我要感谢MBo和未来学家的宝贵投入

虽然我没能让他们的例子起作用(更可能是因为我错了),但他们的回答为我指明了正确的方向,并指向了那个尤里卡时刻

关键在于交换正确的向量

谢谢你们两位,你们真的帮了我。这是我的最终(工作)代码:

//设置一些变量
角度=123*pi/180;
半径=4;
//P1和P2表示形成直线的向量。
dx=p2x-p1x;
dy=p2y-p1y;
dz=p2z-p1z;
d=sqrt(dx*dx+dy*dy+dz*dz)
//归一化向量
v3x=dx/d;
v3y=dy/d;
v3z=dz/d;
//将向量元素存储在数组中
p=[v3x,v3y,v3z];
//将向量元素存储在第二个数组中,这次使用绝对值
p_abs=[abs(v3x)、abs(v3y)、abs(v3z)];
//查找具有最大和最小震级的元素
maxval=max(p_abs[0],p_abs[1],p_abs[2]);
minval=min(p_abs[0],p_abs[1],p_abs[2]);
//初始化3个变量以存储包含(最大、中等、最小)向量大小的数组索引。
maxindex=0;
medindex=0;
minindex=0;
//通过p_abs数组循环,找出哪些震级等于maxval和minval。存储它们的索引以供以后使用。
对于(i=0;i<3;i++){
如果(p_abs[i]==maxval)maxindex=i;
如果(p_abs[i]=minval)minindex=i;
}
//找到具有中等震级的剩余索引
对于(i=0;i<3;i++){
如果(i!=maxindex&&i!=minindex){
medindex=i;
打破
}
}
//暂时存储最大震级。
storemax=(p[maxindex]);
//交换包含最大和中等震级的两个索引,取最大值的负数。将最小幅值设置为零。
p[maxindex]=(p[medindex]);
p[medindex]=-storemax;
p[minindex]=0;
//计算v1。垂直于v3。
s=sqrt(v3x*v3x+v3z*v3z+v3y*v3y);
v1x=s*p[0];
v1y=s*p[1];
v1z=s*p[2];
//将v2计算为v3和v1的叉积。
v2x=v3y*v1z-v3z*v1y;
v2y=v3z*v1x-v3x*v1z;
v2z=v3x*v1y-v3y*v1x;
//对于每个圆点。
圆点x=p2x+半径*(v1x*cos(角度)+v2x*sin(角度))
圆点=p2y+半径*(v1y*cos(角度)+v2y*sin(角度))
圆点Z=p2z+半径*(v1z*cos(角度)+v2z*sin(角度))

你的问题太模糊了,但我想你真正想要的是什么

您有一条直线穿过两点
p1
p2
。您需要构建一个半径为
r
的圆,以
p1
为中心,并垂直于直线

首先找到这条线的方向向量-你们已经知道如何-标准化向量
v3

现在您需要垂直于
v3
的任意向量:查找具有最大幅值和第二幅值的
v3
分量。例如,
abs(v3y)
为最大值,
abs(v3x)
为第二个值。交换它们,取最大值的反,并使第三个分量为零:

p = (-v3y, v3x, 0)
该向量与
v3
垂直(其点积为零)

现在让它正常化

pp = p / length(p)
现在将副法线向量作为
v3
pp
的叉积(我有单位长度,不需要归一化),它垂直于
v3
pp

b = v3 x pp
现在建立所需的循环

circlepoint(theta) = p1 + radius * pp * Cos(theta) + radius * b * Sin(theta)
还要注意,弧度的角度是

angle = degrees * pi / 180
Python中的测试示例:

将numpy导入为np
#输入:
#确定线L的一对点:
P1=np.数组([1,1,1])
P2=np.数组([3,2,3])
半径=3
V3=P1-P2
V3=V3/np.linalg.norm(V3)
e=np.数组([0,0,0])
e[np.argmin(np.abs(V3))]=1
V1=np.交叉(e,V3)
V1=V1/np.linalg.norm(V3)
V2=np.交叉(V3,V1)
#例如,假设您希望将点P沿圆旋转60度(相对于V1):
s=np.pi/3
P=P1+半径*(正余弦*V1+正余弦*V2)

我已将
java
c++
标记替换为
language agnostic
,因为您明确希望了解与该语言无关的内容。如果这不是你的意图,请告诉我。我已经更新了我的问题,让它更清楚(还有弧度的问题)。为了澄清,在你的例子中,向量p元素x,y,z分别变成-v3y,v3x,0?是的,完全正确。我似乎很理解你的需要。如果这是假设我已经有了一个关于这条线的观点,恐怕我没有。我已经更新了我的答案,让事情更清楚一点。@pJay现在怎么办。基本上,求半径为R的圆的方程,以点P1为中心,位于穿过点P1的平面内,并垂直于线P1 P2。
angle = degrees * pi / 180
#Input:
# Pair of points which determine line L: 
P1 = [x_P1, y_P1, z_P1]
P2 = [x_P1, y_P1, z_P1]

# Radius:
Radius = R

# unit vector aligned with the line passing through the points P1 and P2:
V3 = P1 - P2
V3 = V3 / norm(V3)

# from the three basis vectors, e1 = [1,0,0], e2 = [0,1,0], e3 = [0,0,1] 
# pick the one that is the most transverse to vector V3
# this means, look at the entries of V3 = [x_V3, y_V3, z_V3] and check which
# one has the smallest absolute value and record its index. Take the coordinate 
# vector that has 1 at that selected index. In other words, 
# if min( abs(x_V3), abs(y_V)) = abs(y_V3), 
# then argmin( abs(x_V3), abs(y_V3), abs(z_V3)) = 2 and so take e = [0,1,0]:   
e = [0,0,0]
i = argmin( abs(V3[1]), abs(V3[2]), abs(V3[3]) )
e[i] = 1

# a unit vector perpendicular to both e and V3:  
V1 = cross(e, V3)
V1 = V1 / norm(V1)

# third unit vector perpendicular to both V3 and V1:
V2 = cross(V3, V1)

# an arbitrary point on the circle (i.e. equation of the circle with parameter s):
P = P1 + Radius*( np.cos(s)*V1 + np.sin(s)*V2 ) 


# E.g. say you want to find point P on the circle, 60 degrees relative to vector V1:
s = pi/3
P = P1 + Radius*( cos(s)*V1 + sin(s)*V2 )