始点と終点と半径から円孤の中心を求める関数です。中心の数は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関数を修正しました。