始点と終点と半径から円孤の中心を求める関数です。中心の数は0個、1個、2個の3パターンあるので、それを返り値とします。
function SER2ArcCenterV(pt1, pt2 :vector; rad :real; var cnt1, cnt2 :vector): integer;
{ 始点と終点と半径から円の中心を求める(返り値は中心の数)(vector型) }
var
ang, dia, dist, h, prec :real;
result :integer;
pm, v :vector;
begin
result:= 0;
Vec2AD(pt2 - pt1, ang, dist);
dia:= Abs(2 * rad);
prec:= LargeR(dist, dia) * PrecFactor;
pm:= (pt1 + pt2) / 2;
if Abs(dist - dia) <= prec then begin
result:= 1;
cnt1:= pm;
end
else if Abs(2 * rad) > dist then begin
result:= 2;
v:= Ang2Vec(ang + 90, 1);
h:= Sqrt(rad^2 - (dist/2)^2);
cnt1:= pm + h * v;
cnt2:= pm - h * v;
end;
SER2ArcCenterV:= result;
end;
真面目に書いたら上のようになりましたが、新ためて説明図を眺めいたら、pt1とpt2間の中間二等分線とpt1かpt2を中心とした円との交点を求めれば良いと気付きました。それからIntersectLCVのソースコードを見直したら、書いた人が同じだから当たり前なのですが、ほとんど同じことを書いている!
そこで下のように書き直しました。
function SER2ArcCenterV(pt1, pt2 :vector; rad :real; var cnt1, cnt2 :vector): integer;
{ 始点と終点と半径から円の中心を求める(返り値は中心の数)(vector型) }
var
p1, p2 :real;
begin
PerpendicularBisectV(pt1, pt2, p1, p2);
SER2ArcCenterV:= IntersectLCV(p1, p2, pt1, rad, cnt1, cnt2);
end;
function SER2ArcCenterP(pt1, pt2 : point; rad :real; var pc1, pc2 :point): integer;
{ 始点と終点と半径から円の中心を求める(返り値は中心の数)(point型) }
var
p1, p2 :vector;
begin
SER2ArcCenterP:= SER2ArcCenterV(Pt2Vec(pt1), Pt2Vec(pt2), rad, p1, p2);
pc1:= Vec2Pt(p1); pc2:= Vec2Pt(p2);
end;
function SER2ArcCenterR(x1, y1, x2, y2, rad :real; var xc1, yc1, xc2, yc2 :real): integer;
{ 始点と終点と半径から円の中心を求める(返り値は中心の数)(real型) }
var
p1, p2 :vector;
begin
SER2ArcCenterR:= SER2ArcCenterV(XY2Vec(x1, y1), XY2Vec(x2, y2), rad, p1, p2);
Vec2XY(p1, xc1, yc1); Vec2XY(p2, xc2, yc2);
end;
追記:2点間=直径のときに中心点が取れなかったので、IntersectLCV関数を修正しました。