绘制三点圆弧

问题:提供圆弧两端点和弧上一点,编程绘制三点圆弧?
关键:如何求解创建圆弧时的角度顺序,保证圆弧经过指定的弧上点。

步骤

  • 确定圆心和半径
  • 分别求两端点及弧上点与圆心连线的角度∠1、∠2、∠3(转换为0~2π范围)
  • 取∠1<∠2
  • 判断∠3是否在∠1→∠2之间
  • 如果是,绘制∠1→∠2圆弧,否则绘制∠2→∠1圆弧

细节

  • 三点互异
  • 三点不共线
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/// <summary>
/// 三点创建圆弧
/// </summary>
/// <param name="endPoint1">圆弧端点之一</param>
/// <param name="endPoint2">圆弧端点之一</param>
/// <param name="pointOnArc">弧上一点</param>
/// <returns>创建的圆弧</returns>
public static Arc CreateArcByThreePoints(Point3d endPoint1, Point3d endPoint2, Point3d pointOnArc) {
if (endPoint1 == endPoint2 || endPoint2 == pointOnArc || pointOnArc == endPoint1
|| AreThreePointsOnLine(endPoint1, endPoint2, pointOnArc))
return null;

CircularArc3d circle = new CircularArc3d(endPoint1, pointOnArc, endPoint2);
double R = circle.Radius;
Point3d center = circle.Center;

double angle1 = Math.Atan2(endPoint1.Y - center.Y, endPoint1.X - center.X);
if (angle1 < 0) angle1 += Math.PI * 2;
double angle2 = Math.Atan2(endPoint2.Y - center.Y, endPoint2.X - center.X);
if (angle2 < 0) angle1 += Math.PI * 2;
double angle3 = Math.Atan2(pointOnArc.Y - center.Y, pointOnArc.X - center.X);
if (angle3 < 0) angle1 += Math.PI * 2;

if (angle1 < angle2) {
double temp = angle1;
angle1 = angle2;
angle2 = temp;
}

Arc arc = new Arc(center, R, angle2, angle1);
if (angle3 > angle1 && angle3 < angle2)
arc = new Arc(center, R, angle1, angle2);

return arc;
}

/// <summary>
/// 判断三点是否共线
/// </summary>
/// <param name="p1">点1</param>
/// <param name="p2">点2</param>
/// <param name="p3">点3</param>
/// <returns>共线返回true,否则返回false</returns>
public static bool AreThreePointsOnLine(Point3d p1, Point3d p2, Point3d p3) {
Vector2d v13 = new Vector2d(p3.X - p1.X, p3.Y - p1.Y);
Vector2d v23 = new Vector2d(p3.X - p2.X, p3.Y - p2.Y);
return v13.IsParallelTo(v13);
}

评论