图纸中角度标注算法

两条非平行线段, 如何合理的标注角度。比方说对于下面2条初始线段:

1

根据当前鼠标所在位置的不同,我们可能得到如下不同的标注方式:

34567

 

本人求标注的思路大体思路是:首先求出圆弧(Dimension Line)的两个端点, 然后根据这两个已求得的端点,分别计算出两条引线(Witness Line)的端点。

求圆弧端点的算法:

我们把问题简化下,对于任意2条相交的射线,以下均以锐角为例(钝角求解过程完全一致):

以2线段所在直线交点作为圆心, 鼠标位置到圆心的距离为半径,画一个圆,2条直线与圆必有4个交点,而Dimension Line的2个端点必然为这4个交点中的两个。

image

问题是我们如何从这4个交点中,选取其中的2个点作为Dimension Line的端点。

方法如下:我们把上面图中的红色实心向量和蓝色实心向量,作为2个参考向量,将图切分为如下4个象限:

 

image

然后根据当前的鼠标位置,决定出应该取那个象限, 做法是 记 value = (红色向量 X 橙色向量) . (橙色向量 X 蓝色向量)

如果得到的value值大于0,则当前鼠标必定落在一三象限,否则则在二四象限

image

接下来就是如何精确点位到鼠标是在一象限呢,还是在三象限。本人想到了用角度去推测,相信应该有更高效便捷的算法存在,只是目前自己没想到。

观察上图我们可以发现:假设当前鼠标在第三象限,那么橙色向量分别到两参考向量(红色实心向量和蓝色实心向量)的角度之和必然大于 180°,如果求得角度和小于180°就可断定为第一象限。(此方法钝角也依然适用,考虑下当前鼠标在上图二象限,以红色虚线向量以及蓝色实线向量作为参考向量)

 

算法实现如下,思路大体跟上面一致,仅做了点优化:

求DimensionLine端点算法
 1  private void GetDimensionLineEndPoints(LineSeg3d firstSeg3d, LineSeg3d secondSeg3d, Point3d thirdPt, out Point3d firstCrossPt, out Point3d secondCrossPt)
 2  {
 3      Point3d centerPoint = GetIntersectPoint(firstSeg3d, secondSeg3d);
 4      double radius = thirdPt.DistanceTo(centerPoint);
 5 
 6      Vector3d firstLineVec = (firstSeg3d.EndPoint - centerPoint).Normal();
 7      Vector3d secondLineVec = (secondSeg3d.EndPoint - centerPoint).Normal();
 8      Vector3d thirdLineVec = (thirdPt - centerPoint).Normal();
 9 
10      if ((firstLineVec.CrossProduct(thirdLineVec)).DotProduct(thirdLineVec.CrossProduct(secondLineVec)) < 0)
11          secondLineVec = -secondLineVec;
12 
13      if ((thirdLineVec.AngleTo(firstLineVec) + thirdLineVec.AngleTo(secondLineVec)) > Math.PI)
14      {
15          firstLineVec = -firstLineVec;
16          secondLineVec = -secondLineVec;
17      }
18 
19      firstCrossPt = centerPoint + firstLineVec * radius;
20      secondCrossPt = centerPoint + secondLineVec * radius;
21  }
22 

 

 

求引线端点的算法:

image

Witness Line的2个端点为上述4个点中的两个,组合方式取决于绿色圈圈相对于其他3个点的位置,目前本人想到的方案不是很理想,看看明天能不能想到更方便简单的算法来描述,敬请等待明天的更新。

 

如果大家有更好的标注算法,请不吝指教!

posted @ 2010-11-18 21:58  Anders06  阅读(1976)  评论(6编辑  收藏