问题描述:如何判断某一个点是否位于某条多段线上?
解决思路:现有线段AB,求点C是否位于线段AB上。先分别计算AB、AC的向量,使AB*AC(向量操作),叉乘结果为0(ABC三点共线),则表明在直线AB上。需要进一步判断C是否落在AB线段上,排除落在延长线上的情况。因此,还需要比较ABC的坐标值,具体如下代码:
1、代码
static int isOnLine(AcGePoint2d pa, AcGePoint2d pb, AcGePoint2d pt1)
{
int a = 0, b = 0, c = 0;
AcGeVector2d v1 = pb - pa;
AcGeVector2d v2 = pt1 - pa;
double cross = Cross(v1, v2);
double Xmin_ab = 0, Xmax_ab = 0, Ymin_ab = 0, Ymax_ab = 0;
Xmin_ab = min(pa.x, pb.x);
Xmax_ab = max(pa.x, pb.x);
Ymin_ab = min(pa.y, pb.y);
Ymax_ab = max(pa.y, pb.y);
if (fabs(cross) < 1e-5)//叉乘结果为0,则表示3点共线
{
if (pt1.x >= Xmin_ab && pt1.x <= Xmax_ab)//判断是否在线段上,而不是线段的延长线上
{
if (pt1.y >= Ymin_ab && pt1.y <= Ymax_ab)
{
a = 1;//点在线上(含端点)
}
}
}
//考虑到计算容差问题,补充线段上两个端点与目标点重合的判断逻辑
if (fabs(pt1.x - pa.x) < EPS && fabs(pt1.y - pa.y) < EPS)
{
//目标点与端点a重合
b = 1;
}
if (fabs(pt1.x - pb.x) < EPS && fabs(pt1.y - pb.y) < EPS)
{
//目标点与端点b重合
c = 1;
}
if (a == 1 || b == 1 || c == 1)
{
return 1;//该点位于线段上
}
else
{
return 2;//该点不在线段上
}
}
由于CAD的计算精度问题,需要设置一个容差值EPS,在容差范围内则复合要求。
代码添加了与首尾端点重合的情况,考虑到的是容差问题,当C与A或B重合时,坐标XY不一定在double类型上表现为完全相等,因此需要添加符合容差范围内相等即可的判断代码,即后面两个if语句的作用。
一般写CAD代码,都不可忽略容差值问题,否则将会出现很多问题。
主要用到的方法是向量叉乘,叉乘结果为0,表示三点共线,在进一步判断是否位于坐标范围内即可。
1794

被折叠的 条评论
为什么被折叠?



