几何弧算法
Geometry Arc Algorithm
我搜索了整个互联网,没有找到任何解决这个问题的伪代码,
我想使用 5 个参数在 A 和 B 两点之间找到弧线:
- 起点
- 终点
- 半径(不知道是否需要)
- 角度
- 质量
示例:
StartPoint = 左边的绿点是参数上设置的Start Point
EndPoint = 右边的绿点是参数上设置的End Point
角度 = 圆弧的角度(半圆)
质量 = 要创建多少个红色圆圈
我想有一个伪代码来解决这个问题
提前致谢:D
设起点为P0,终点为P1,角度为Fi。 不需要R
首先求圆心。获取 P0-P1 段的中间。
M = (P0 + P1) / 2
// M.x = (P0.x + P1.x) / 2 , same for y
和方向向量
D = (P1 - P0) / 2
获取D的长度
lenD = Math.Hypot(D.x, D.y) //Vector.Length, sqrt of sum of squares
获取单位向量
uD = D / lenD
获取(左)垂直矢量
(P.x, P.y) = (-uD.y, ud.x)
现在圆心
if F = Pi then
C.x = M.x
C.y = M.y
else
C.x = M.x + P.x * Len / Tan(Fi/2)
C.y = M.y + P.y * Len / Tan(Fi/2)
从中心到起点的向量:
CP0.x = P0.x - C.x
CP0.y = P0.y - C.y
然后用矢量CP0绕中心点旋转,就可以计算出圆弧上N个中间点的坐标
an = i * Fi / (NSeg + 1);
X[i] = C.x + CP0.x * Cos(an) - CP0.y * Sin(an)
Y[i] = C.y + CP0.x * Sin(an) + CP0.y * Cos(an)
工作 Delphi 代码
procedure ArcByStartEndAngle(P0, P1: TPoint; Angle: Double; NSeg: Integer);
var
i: Integer;
len, dx, dy, mx, my, px, py, t, cx, cy, p0x, p0y, an: Double;
xx, yy: Integer;
begin
mx := (P0.x + P1.x) / 2;
my := (P0.y + P1.y) / 2;
dx := (P1.x - P0.x) / 2;
dy := (P1.y - P0.y) / 2;
len := Math.Hypot(dx, dy);
px := -dy / len;
py := dx / len;
if Angle = Pi then
t := 0
else
t := len / Math.Tan(Angle / 2);
cx := mx + px * t;
cy := my + py * t;
p0x := P0.x - cx;
p0y := P0.y - cy;
for i := 0 to NSeg + 1 do begin
an := i * Angle / (NSeg + 1);
xx := Round(cx + p0x * Cos(an) - p0y * Sin(an));
yy := Round(cy + p0x * Sin(an) + p0y * Cos(an));
Canvas.Ellipse(xx - 3, yy - 3, xx + 4, yy + 4);
end;
end;
(Point(100, 0), Point(0, 100), Pi / 2, 8
的结果(Y 轴在图片下方)
我搜索了整个互联网,没有找到任何解决这个问题的伪代码, 我想使用 5 个参数在 A 和 B 两点之间找到弧线:
- 起点
- 终点
- 半径(不知道是否需要)
- 角度
- 质量
示例:
StartPoint = 左边的绿点是参数上设置的Start Point
EndPoint = 右边的绿点是参数上设置的End Point
角度 = 圆弧的角度(半圆)
质量 = 要创建多少个红色圆圈
我想有一个伪代码来解决这个问题
提前致谢:D
设起点为P0,终点为P1,角度为Fi。 不需要R
首先求圆心。获取 P0-P1 段的中间。
M = (P0 + P1) / 2
// M.x = (P0.x + P1.x) / 2 , same for y
和方向向量
D = (P1 - P0) / 2
获取D的长度
lenD = Math.Hypot(D.x, D.y) //Vector.Length, sqrt of sum of squares
获取单位向量
uD = D / lenD
获取(左)垂直矢量
(P.x, P.y) = (-uD.y, ud.x)
现在圆心
if F = Pi then
C.x = M.x
C.y = M.y
else
C.x = M.x + P.x * Len / Tan(Fi/2)
C.y = M.y + P.y * Len / Tan(Fi/2)
从中心到起点的向量:
CP0.x = P0.x - C.x
CP0.y = P0.y - C.y
然后用矢量CP0绕中心点旋转,就可以计算出圆弧上N个中间点的坐标
an = i * Fi / (NSeg + 1);
X[i] = C.x + CP0.x * Cos(an) - CP0.y * Sin(an)
Y[i] = C.y + CP0.x * Sin(an) + CP0.y * Cos(an)
工作 Delphi 代码
procedure ArcByStartEndAngle(P0, P1: TPoint; Angle: Double; NSeg: Integer);
var
i: Integer;
len, dx, dy, mx, my, px, py, t, cx, cy, p0x, p0y, an: Double;
xx, yy: Integer;
begin
mx := (P0.x + P1.x) / 2;
my := (P0.y + P1.y) / 2;
dx := (P1.x - P0.x) / 2;
dy := (P1.y - P0.y) / 2;
len := Math.Hypot(dx, dy);
px := -dy / len;
py := dx / len;
if Angle = Pi then
t := 0
else
t := len / Math.Tan(Angle / 2);
cx := mx + px * t;
cy := my + py * t;
p0x := P0.x - cx;
p0y := P0.y - cy;
for i := 0 to NSeg + 1 do begin
an := i * Angle / (NSeg + 1);
xx := Round(cx + p0x * Cos(an) - p0y * Sin(an));
yy := Round(cy + p0x * Sin(an) + p0y * Cos(an));
Canvas.Ellipse(xx - 3, yy - 3, xx + 4, yy + 4);
end;
end;
(Point(100, 0), Point(0, 100), Pi / 2, 8
的结果(Y 轴在图片下方)