現状の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日、あはら)