現状のEvaluateはこうなっている。
case CONST_MEET_CC:
if(CInput1==NULL || CInput2==NULL || POutput==NULL){
return true;
}
c1x=CInput1->xx;c1y=CInput1->yy;c1r=CInput1->rr;
c2x=CInput2->xx;c2y=CInput2->yy;c2r=CInput2->rr;
lx=CComplex(2.0,0.0)*(c1x-c2x);
ly=CComplex(2.0,0.0)*(c1y-c2y);
lz=c1r-c2r-c1x*c1x-c1y*c1y+c2x*c2x+c2y*c2y;
if(lx.zerop() && ly.zerop()){
POutput->xx==CComplex(1.0,0.0);
POutput->yy==CComplex(1.0,0.0);
POutput->zz==CComplex(0.0,0.0);
return true;
}
if(ly.zerop()){
Meet_CL(ly,lx,lz,c1y,c1x,c1r,&yy1,&yy2);
xx1 = xx2 = CComplex(-1.0,0.0)* lz / lx;
}
else {
Meet_CL(lx,ly,lz,c1x,c1y,c1r,&xx1,&xx2);
yy1 = CComplex(-1.0,0.0)* (lx * xx1 + lz ) / ly;
yy2 = CComplex(-1.0,0.0)* (lx * xx2 + lz ) / ly;
}
n1=norm(xx1-para1)+norm(yy1-para2);
n2=norm(xx2-para1)+norm(yy2-para2);
if(n1+0.01<n2){
POutput->xx = xx1;
para1 = xx1;
POutput->yy = yy1;
para2 = yy1;
}
else {
POutput->xx = xx2;
para1 = xx2;
POutput->yy = yy2;
para2 = yy2;
}
POutput->zz = CComplex(1.0,0.0);
break;
つまり、まず二つの交点を(xx1,yy1),(xx2,yy2)で求めておいて、今の場所(para1,para2)からみて近い方を選んでいる。(para1,para2)は「前回の交点」なわけだ。
そこで、次のような作戦はどうか。
xx1が実数でなければyy1,xx2,yy2も実数でない。(なぜかというと、実数係数の連立2次方程式を解いているので。)一方で、(para1,para2)が実数の組だったならば、ここで、「接点を通過」していることがわかる。接点では(para1,para2)両方ともがそれぞれの方程式の重根になっている。一方で、xx1,xx2はpara1ととても近いはずである。このことから、「para1から見て(複素数平面上で)右側に見える方へ進む。」とする。
xx1が実数で(したがって、yy1,xx2,yy2も実数)para1が複素数のときにもやはり、「para1から見て(複素数平面上で)右側に見える方へ進む。」というルールで次の道を決める。
これで数学的には「重根を右によける」という処理と同じことになる。
(7月31日、あはら)
そこで、次のような作戦はどうか。
xx1が実数でなければyy1,xx2,yy2も実数でない。(なぜかというと、実数係数の連立2次方程式を解いているので。)一方で、(para1,para2)が実数の組だったならば、ここで、「接点を通過」していることがわかる。接点では(para1,para2)両方ともがそれぞれの方程式の重根になっている。一方で、xx1,xx2はpara1ととても近いはずである。このことから、「para1から見て(複素数平面上で)右側に見える方へ進む。」とする。
xx1が実数で(したがって、yy1,xx2,yy2も実数)para1が複素数のときにもやはり、「para1から見て(複素数平面上で)右側に見える方へ進む。」というルールで次の道を決める。
これで数学的には「重根を右によける」という処理と同じことになる。
(7月31日、あはら)