我有四个点p0,p1,p1',p2',每个点都由x,y,z分量定义,并且全部位于一行,如图所示
我想从四点之间的交点得到线段(虚线部分)
使用C#
的任何建议或示例代码答案 0 :(得分:1)
这或多或少与霍华德给出的答案相同,但压入C#...我希望这有助于您的代码库。
这个代码片段应该可以解决问题(从你的4中找到中间点,但只有当它们都是共线的时候) - 还要注意我没有检查真正的交叉点,你可以通过检查答案来轻松地做到这一点。你的观点。 我没有花时间以合理的方式实现Vector3D结构(运算符,......) - 你也可以轻松地做到这一点。 另请注意,这不仅适用于4点,还要牢记您的图表。
private struct Vector3D
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
static class Vectors
{
static public double ScalProd(Vector3D v1, Vector3D v2)
{
return v1.X*v2.X + v1.Y*v2.Y + v1.Z*v2.Z;
}
static public Vector3D Minus(Vector3D v1, Vector3D v2)
{
return new Vector3D {X = v1.X - v2.X, Y = v1.Y - v2.Y, Z = v1.Z - v2.Z};
}
static public Vector3D Normalize(Vector3D v)
{
var len = Math.Sqrt(ScalProd(v, v));
return new Vector3D {X = v.X/len, Y = v.Y/len, Z = v.Z/len};
}
}
private Vector3D[] FindIntersectionOnCoLinearVectors(params Vector3D[] input)
{
if (input.Length < 2) throw new Exception("you need a minimum of two vectors");
var v0 = input[0];
var direction = Vectors.Normalize(Vectors.Minus(input[1], v0));
Func<Vector3D, double> projectOntoLineStartingAtv0 =
v => Vectors.ScalProd(direction, Vectors.Minus(v, v0));
var mapped = input.OrderBy(projectOntoLineStartingAtv0).ToArray();
return new Vector3D[] {mapped[1], mapped[2] };
}
答案 1 :(得分:0)
您可以按以下步骤操作:
第1步:转变为1D问题
t(P) = (P-P0).(P1-P0) / (P1-P0).(P1-P0)
,其中点表示标量积t
是通过P1
和P0
t(P0)=0
,t(P1)=1
第2步:解决1D中的问题
t(P0') <= t(P1')
(否则在以下行中交换P0'
和P1'
)t(P1') < 0
=&gt;没有交集1 < t(P0')
=&gt;没有交集t(P0') <= 0 <= t(P1') <= 1
=&gt;交集是段(P0,P1')
t(P0') <= 0 < 1 < t(P1')
=&gt;交集是段(P0,P1)
0 <= t(P0') <= t(P1') <= 1
=&gt;交集是段(P0',P1')
0 <= t(P0') <= 1 < t(P1')
=&gt;交集是段(P0',P1)
t
- 值感兴趣,则交叉点由t0 = max(0, t(P0'))
和t1 = min(1, t(P1'))
iff t0 <= t1