在道路设计相关三维软件开发过程中,有时候我们需要判断路线两边的点具体是位于左右哪一侧。目前Mstn SDK的编程框架中没有可以直接获取此项信息的接口函数,不过我们可以利用编程框架中已有的几何计算接口来自行判断。当然对于同一条路线而言,不同的行驶方向,左右侧也是相反的。我们以路线的前进方向(路线起点到终点这一方向)为例去判断指定的空间点位于路线的哪一侧。Mstn SDK中有一个mdlElmdscr_distanceAtPoint函数,其原型如下所示:
MSCORE_EXPORT int mdlElmdscr_distanceAtPoint ( double *distance, Dpoint3d *position, Dpoint3d *tangent, MSElementDescrP edP, Dpoint3d *inputPoint, double inputTolerance );
这个函数可以返回指定的路线元素上,距离指定点最近点的详细信息,包括切向量、坐标等。我们得到切向量和路线上的最近点以后,可以构造一个最近点到所求点的向量。然后判断切向量到我们构造的这个向量之间的角度,最后通过判断这个角度就可以判断出来所求点在路线前进方向上位于路线的左侧还是右侧。求两个向量之间的可以通过另外一个函数mdlVec_angleBetweenVectorsXY实现,其原型如下所示:
MSCORE_EXPORT double mdlVec_angleBetweenVectorsXY ( DPoint3dCP Vector1, DPoint3dCP Vector2 );
具体实现代码如下所示:
int JudgeLeftRightSide(EditElementHandleR eehLine, DPoint3dR pt) { DPoint3d pos; DVec3d tan; if (SUCCESS != mdlElmdscr_distanceAtPoint(NULL, &pos, &tan, eehLine.GetElementDescrP(), &pt, 0)) return 0; DVec3d vecNormal = DVec3d::FromStartEndNormalize(pos, pt); tan.Normalize(); vecNormal.Normalize(); if (1 == tan.z || 1 == vecNormal.z) return 0; double angle = mdlVec_angleBetweenVectorsXY(&tan, &vecNormal); if (angle > 0 && angle < fc_pi) return -1; return 1; }
函数返回值为0时表示传入的坐标点或者路线元素有误,返回-1表示在左侧,返回1表示在右侧。