惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
博客园 - 司徒正美
Last Week in AI
Last Week in AI
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
博客园 - 聂微东
M
MIT News - Artificial intelligence
博客园_首页
Jina AI
Jina AI
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
Vercel News
Vercel News
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
N
Netflix TechBlog - Medium
B
Blog
Google DeepMind News
Google DeepMind News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Anders06

A memory leak issue with WPF Command Binding 我也谈面试 附赠一份题目 败给了IEqualityComparer 标注随测量物体旋转问题 How to detect memory leak issue 认真的程序员最可爱 Clean Code反案例:什么是不好的API 避免陷阱,重写Equals方法您需要注意的其中2个原则 What’s the problems with the following code 对象池 关于设计和设计文档的2个补充 SelectMany ConverAll & Exists SOS:利用WPF RichTextBox 提取RTF, 莫名丢掉了Underline样式信息 想探讨两个关于设计文档问题 Don‘t Cry for Me, Argentina 拒绝高姿态 Please avoid implement C# Destruction SOS: How to popup a HwndSource on topmost
图纸中角度标注算法
Anders06 · 2010-11-18 · via 博客园 - Anders06

两条非平行线段, 如何合理的标注角度。比方说对于下面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个点的位置,目前本人想到的方案不是很理想,看看明天能不能想到更方便简单的算法来描述,敬请等待明天的更新。

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