图纸中角度标注算法
两条非平行线段, 如何合理的标注角度。比方说对于下面2条初始线段:
根据当前鼠标所在位置的不同,我们可能得到如下不同的标注方式:
本人求标注的思路大体思路是:首先求出圆弧(Dimension Line)的两个端点, 然后根据这两个已求得的端点,分别计算出两条引线(Witness Line)的端点。
求圆弧端点的算法:
我们把问题简化下,对于任意2条相交的射线,以下均以锐角为例(钝角求解过程完全一致):
以2线段所在直线交点作为圆心, 鼠标位置到圆心的距离为半径,画一个圆,2条直线与圆必有4个交点,而Dimension Line的2个端点必然为这4个交点中的两个。
问题是我们如何从这4个交点中,选取其中的2个点作为Dimension Line的端点。
方法如下:我们把上面图中的红色实心向量和蓝色实心向量,作为2个参考向量,将图切分为如下4个象限:
然后根据当前的鼠标位置,决定出应该取那个象限, 做法是 记 value = (红色向量 X 橙色向量) . (橙色向量 X 蓝色向量)
如果得到的value值大于0,则当前鼠标必定落在一三象限,否则则在二四象限
接下来就是如何精确点位到鼠标是在一象限呢,还是在三象限。本人想到了用角度去推测,相信应该有更高效便捷的算法存在,只是目前自己没想到。
观察上图我们可以发现:假设当前鼠标在第三象限,那么橙色向量分别到两参考向量(红色实心向量和蓝色实心向量)的角度之和必然大于 180°,如果求得角度和小于180°就可断定为第一象限。(此方法钝角也依然适用,考虑下当前鼠标在上图二象限,以红色虚线向量以及蓝色实线向量作为参考向量)
算法实现如下,思路大体跟上面一致,仅做了点优化:

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
求引线端点的算法:
Witness Line的2个端点为上述4个点中的两个,组合方式取决于绿色圈圈相对于其他3个点的位置,目前本人想到的方案不是很理想,看看明天能不能想到更方便简单的算法来描述,敬请等待明天的更新。
如果大家有更好的标注算法,请不吝指教!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?