检查一个点是否在三维空间的直线上
本文关键字:三维空间 是否 一个 检查 | 更新日期: 2023-09-27 18:10:21
这个方法应该告诉你一个点是否在给定的行上。目前,只要方向矢量的分量不为0(我使用的是直线的参数表示),它就可以正常工作。如果没有0,我应该得到xResult=yResult=zResult,如果点在直线上。如果方向向量上有一个0,这三个中至少有一个是0因此不等于其他的,但是这个点仍然可以在直线上。
找到一个点是否在给定的行上,处理零情况的最好方法是什么?
/// <summary>
/// Returns true if the passed point is on the line, false otherwise
/// </summary>
/// <param name="passedPoint"></param>
/// <returns></returns>
public Boolean IsOnLine(Line passedLine)
{
Boolean pointIsOnLine = false;
//Get components of this point
Dimension xPoint = new Dimension(DimensionType.Millimeter, X.Millimeters);
Dimension yPoint = new Dimension(DimensionType.Millimeter, Y.Millimeters);
Dimension zPoint = new Dimension(DimensionType.Millimeter, Z.Millimeters);
//Get components of the base point of the line
Dimension xBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.X.Millimeters);
Dimension yBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.Y.Millimeters);
Dimension zBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.Z.Millimeters);
//Find difference between passed point and the base point
Dimension xDifference = xPoint - xBasePoint;
Dimension yDifference = yPoint - yBasePoint;
Dimension zDifference = zPoint - zBasePoint;
DimensionGenerator dg = new DimensionGenerator(DimensionType.Millimeter);
//Instantiate the 3 result variables
Dimension xResult = dg.MakeDimension(-1);
Dimension yResult = dg.MakeDimension(-1);
Dimension zResult = dg.MakeDimension(-1);
//Solve for the multiplier using each direction and make sure they are all equal.
//If any component of the direction vector is 0, the result will be zero and should therefore be directly assigned to 0 to avoid dividing by 0
if(passedLine.XComponentOfDirection.Millimeters == 0)
{
xResult = dg.MakeDimension(0);
}
if(passedLine.YComponentOfDirection.Millimeters == 0)
{
yResult = dg.MakeDimension(0);
}
if(passedLine.ZComponentOfDirection.Millimeters == 0)
{
zResult = dg.MakeDimension(0);
}
else
{
xResult = dg.MakeDimension(xDifference.Millimeters / passedLine.XComponentOfDirection.Millimeters);
yResult = dg.MakeDimension(yDifference.Millimeters / passedLine.YComponentOfDirection.Millimeters);
zResult = dg.MakeDimension(zDifference.Millimeters / passedLine.ZComponentOfDirection.Millimeters);
}
//If the 3 results are equal, the point is on the line. If they are not, the point is not on the line.
if (xResult == yResult && xResult == zResult)
{
pointIsOnLine = true;
}
else
{
pointIsOnLine = false;
}
return pointIsOnLine;
如果处理的是不精确的数字,比较是否相等是个坏主意。我会尝试下面的方法:从直线的基点到该点取向量,然后取直线的方向向量。计算它们的外积。如果这个点在直线上,这两个向量就共线,它们的叉乘就是0向量。因此,计算向量的平方长度(以避免不必要的平方根),如果它低于某个阈值,则点位于所讨论的直线上。
但是如果您想更接近您自己的代码,请注意您有三个if
,后面跟着一个else
。所以else语句块仍然会被执行如果其中一个first to条件适用。这可能会给你带来麻烦。还请注意,如果您以毫米为单位进行所有计算,则可以通过处理原始数字来节省大量代码。
我建议用另一种方式处理这件事。使用数学。如果任意两个向量之间的夹角为0,则这两个向量"共享一条直线"。
cos(θ)= (U * V)/(U V * | | | |)(积)。
应用于你的代码:
double inverse = ((xPoint*xBasePoint) + (yPoint*yBasePoint) + (zPoint*zBasePoint))/((sqrt(xPoint^2 +yPoint^2 + zPoint^2) + sqrt(xBasePoint^2 + yBasePoint^2 + zBasePoint^2));
if(inverse == 1)
//points are on the same line
else
//points are not on the same line or one point is (0,0,0)
另外,在分配xresult、yresult和zresult时,请查看if else语句。如果passsedline,最后还是会除以0。Z不为0(转到else语句)