Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geomtest3d.cpp
3206 views
#include <mystdlib.h>1#include <myadt.hpp>23#include <linalg.hpp>4#include <gprim.hpp>56namespace netgen7{8int9IntersectTriangleLine (const Point<3> ** tri, const Point<3> ** line)10{11Vec3d vl(*line[0], *line[1]);12Vec3d vt1(*tri[0], *tri[1]);13Vec3d vt2(*tri[0], *tri[2]);14Vec3d vrs(*tri[0], *line[0]);1516static DenseMatrix a(3), ainv(3);17static Vector rs(3), lami(3);18int i;1920/*21(*testout) << "Tri-Line inters: " << endl22<< "tri = " << *tri[0] << ", " << *tri[1] << ", " << *tri[2] << endl23<< "line = " << *line[0] << ", " << *line[1] << endl;24*/25for (i = 1; i <= 3; i++)26{27a.Elem(i, 1) = -vl.X(i);28a.Elem(i, 2) = vt1.X(i);29a.Elem(i, 3) = vt2.X(i);30rs.Elem(i) = vrs.X(i);31}3233double det = a.Det();3435double arel = vl.Length() * vt1.Length() * vt2.Length();36/*37double amax = 0;38for (i = 1; i <= 9; i++)39if (fabs (a.Get(i)) > amax)40amax = fabs(a.Get(i));41*/42// new !!!!43if (fabs (det) <= 1e-10 * arel)44{45#ifdef DEVELOP46// line parallel to triangle !47// cout << "ERROR: IntersectTriangleLine degenerated" << endl;48// (*testout) << "WARNING: IntersectTriangleLine degenerated\n";49/*50(*testout) << "lin-tri intersection: " << endl51<< "line = " << *line[0] << " - " << *line[1] << endl52<< "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl53<< "lami = " << lami << endl54<< "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl55<< " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl56<< " a = " << a << endl57<< " ainv = " << ainv << endl58<< " det(a) = " << det << endl59<< " rs = " << rs << endl;60*/61#endif62return 0;63}6465CalcInverse (a, ainv);66ainv.Mult (rs, lami);6768// (*testout) << "lami = " << lami << endl;6970double eps = 1e-6;71if (72(lami.Get(1) >= -eps && lami.Get(1) <= 1+eps &&73lami.Get(2) >= -eps && lami.Get(3) >= -eps &&74lami.Get(2) + lami.Get(3) <= 1+eps) && !75(lami.Get(1) >= eps && lami.Get(1) <= 1-eps &&76lami.Get(2) >= eps && lami.Get(3) >= eps &&77lami.Get(2) + lami.Get(3) <= 1-eps) )787980{81#ifdef DEVELOP82// cout << "WARNING: IntersectTriangleLine degenerated" << endl;83(*testout) << "WARNING: IntersectTriangleLine numerical inexact" << endl;8485(*testout) << "lin-tri intersection: " << endl86<< "line = " << *line[0] << " - " << *line[1] << endl87<< "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl88<< "lami = " << lami << endl89<< "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl90<< " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl91<< " a = " << a << endl92<< " ainv = " << ainv << endl93<< " det(a) = " << det << endl94<< " rs = " << rs << endl;95#endif96}979899if (lami.Get(1) >= 0 && lami.Get(1) <= 1 &&100lami.Get(2) >= 0 && lami.Get(3) >= 0 && lami.Get(2) + lami.Get(3) <= 1)101{102103return 1;104}105106return 0;107}108109110111112113int IntersectTetTriangle (const Point<3> ** tet, const Point<3> ** tri,114const int * tetpi, const int * tripi)115{116int i, j;117double diam = Dist (*tri[0], *tri[1]);118double epsrel = 1e-8;119double eps = diam * epsrel;120121double eps2 = eps * eps;122int cnt = 0;123124int tetp1 = -1, tetp2 = -1;125int trip1 = -1, trip2 = -1;126int tetp3, tetp4, trip3;127128/*129for (i = 0; i < 4; i++)130loctetpi[i] = -1;131*/132133134if (!tetpi)135{136for (i = 0; i <= 2; i++)137{138// loctripi[i] = -1;139for (j = 0; j <= 3; j++)140{141if (Dist2 (*tet[j], *tri[i]) < eps2)142{143// loctripi[i] = j;144// loctetpi[j] = i;145cnt++;146tetp2 = tetp1;147tetp1 = j;148trip2 = trip1;149trip1 = i;150break;151}152}153}154}155else156{157for (i = 0; i <= 2; i++)158{159// loctripi[i] = -1;160for (j = 0; j <= 3; j++)161{162if (tetpi[j] == tripi[i])163{164// loctripi[i] = j;165// loctetpi[j] = i;166cnt++;167tetp2 = tetp1;168tetp1 = j;169trip2 = trip1;170trip1 = i;171break;172}173}174}175}176177// (*testout) << "cnt = " << cnt << endl;178179180// (*testout) << "tet-trig inters, cnt = " << cnt << endl;181182// cnt .. number of common points183switch (cnt)184{185case 0:186{187Vec3d no, n;188int inpi[3];189190// check, if some trigpoint is in tet:191192for (j = 0; j < 3; j++)193inpi[j] = 1;194195for (i = 1; i <= 4; i++)196{197int pi1 = i % 4;198int pi2 = (i+1) % 4;199int pi3 = (i+2) % 4;200int pi4 = (i+3) % 4;201202Vec3d v1 (*tet[pi1], *tet[pi2]);203Vec3d v2 (*tet[pi1], *tet[pi3]);204Vec3d v3 (*tet[pi1], *tet[pi4]);205Cross (v1, v2, n);206207// n /= n.Length();208double nl = n.Length();209210if (v3 * n > 0)211n *= -1;212213int outeri = 1;214for (j = 0; j < 3; j++)215{216Vec3d v(*tet[pi1], *tri[j]);217if ( v * n < eps * nl)218outeri = 0;219else220inpi[j] = 0;221}222223if (outeri)224return 0;225}226227if (inpi[0] || inpi[1] || inpi[2])228{229return 1;230}231232233// check, if some tet edge intersects triangle:234const Point<3> * line[2], *tetf[3];235for (i = 0; i <= 2; i++)236for (j = i+1; j <= 3; j++)237{238line[0] = tet[i];239line[1] = tet[j];240241if (IntersectTriangleLine (tri, &line[0]))242return 1;243}244245// check, if triangle line intersects tet face:246for (i = 0; i <= 3; i++)247{248for (j = 0; j <= 2; j++)249tetf[j] = tet[(i+j) % 4];250251for (j = 0; j <= 2; j++)252{253line[0] = tri[j];254line[1] = tri[(j+1) % 3];255256if (IntersectTriangleLine (&tetf[0], &line[0]))257return 1;258}259}260261262return 0;263//GH break;264}265case 1:266{267trip2 = 0;268while (trip2 == trip1)269trip2++;270trip3 = 3 - trip1 - trip2;271272tetp2 = 0;273while (tetp2 == tetp1)274tetp2++;275tetp3 = 0;276while (tetp3 == tetp1 || tetp3 == tetp2)277tetp3++;278tetp4 = 6 - tetp1 - tetp2 - tetp3;279280Vec3d vtri1 = *tri[trip2] - *tri[trip1];281Vec3d vtri2 = *tri[trip3] - *tri[trip1];282Vec3d ntri;283Cross (vtri1, vtri2, ntri);284285// tri durch tet ?286// fehlt noch287288289// test 3 tet-faces:290for (i = 1; i <= 3; i++)291{292Vec3d vtet1, vtet2;293switch (i)294{295case 1:296{297vtet1 = *tet[tetp2] - *tet[tetp1];298vtet2 = *tet[tetp3] - *tet[tetp1];299break;300}301case 2:302{303vtet1 = *tet[tetp3] - *tet[tetp1];304vtet2 = *tet[tetp4] - *tet[tetp1];305break;306}307case 3:308{309vtet1 = *tet[tetp4] - *tet[tetp1];310vtet2 = *tet[tetp2] - *tet[tetp1];311break;312}313}314315Vec3d ntet;316Cross (vtet1, vtet2, ntet);317318Vec3d crline = Cross (ntri, ntet);319320double lcrline = crline.Length();321322if (lcrline < eps * eps * eps * eps) // new change !323continue;324325if (vtri1 * crline + vtri2 * crline < 0)326crline *= -1;327328crline /= lcrline;329330double lam1, lam2, lam3, lam4;331LocalCoordinates (vtri1, vtri2, crline, lam1, lam2);332LocalCoordinates (vtet1, vtet2, crline, lam3, lam4);333334if (lam1 > -epsrel && lam2 > -epsrel &&335lam3 > -epsrel && lam4 > -epsrel)336{337338/*339(*testout) << "lcrline = " << lcrline340<< " eps = " << eps << " diam = " << diam << endl;341342(*testout) << "hit, cnt == 1 "343<< "lam1,2,3,4 = " << lam1 << ", "344<< lam2 << ", " << lam3 << ", " << lam4345<< "\n";346*/347return 1;348}349}350return 0;351//GH break;352}353case 2:354{355// common edge356tetp3 = 0;357while (tetp3 == tetp1 || tetp3 == tetp2)358tetp3++;359tetp4 = 6 - tetp1 - tetp2 - tetp3;360trip3 = 3 - trip1 - trip2;361362// (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl;363// (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2364// << ", " << tetp3 << ", " << tetp4 << endl;365366Vec3d vtri = *tri[trip3] - *tri[trip1];367Vec3d vtet1 = *tet[tetp3] - *tri[trip1];368Vec3d vtet2 = *tet[tetp4] - *tri[trip1];369370Vec3d n = *tri[trip2] - *tri[trip1];371n /= n.Length();372373vtet1 -= (n * vtet1) * n;374vtet2 -= (n * vtet2) * n;375376377double lam1, lam2;378LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2);379380if (lam1 < -epsrel || lam2 < -epsrel)381return 0;382else383{384/*385386(*testout) << "vtet1 = " << vtet1 << endl;387(*testout) << "vtet2 = " << vtet2 << endl;388(*testout) << "vtri = " << vtri << endl;389(*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl;390(*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2))391<< " = " << (vtet1 * vtri) << endl;392(*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2))393<< " = " << (vtet2 * vtri) << endl;394395(*testout) << "tet = ";396for (j = 0; j < 4; j++)397(*testout) << (*tet[j]) << " ";398(*testout) << endl;399(*testout) << "tri = ";400for (j = 0; j < 3; j++)401(*testout) << (*tri[j]) << " ";402(*testout) << endl;403404(*testout) << "hit, cnt == 2" << endl;405*/406407return 1;408}409410break;411}412case 3:413{414// common face415return 0;416}417}418419(*testout) << "hit, cnt = " << cnt << endl;420return 1;421}422423424425426427int IntersectTetTriangleRef (const Point<3> ** tri, const int * tripi)428{429int i, j;430double eps = 1e-8;431double eps2 = eps * eps;432433static Point<3> rtetp1(0, 0, 0);434static Point<3> rtetp2(1, 0, 0);435static Point<3> rtetp3(0, 1, 0);436static Point<3> rtetp4(0, 0, 1);437438static const Point<3> * tet[] = { &rtetp1, &rtetp2, &rtetp3, &rtetp4 };439static int tetpi[] = { 1, 2, 3, 4 };440441442// return IntersectTetTriangle (tet, tri, tetpi, tripi);443444445int cnt = 0;446447int tetp1 = -1, tetp2 = -1;448int trip1 = -1, trip2 = -1;449int tetp3, tetp4, trip3;450451/*452if (!tetpi)453{454for (i = 0; i <= 2; i++)455{456for (j = 0; j <= 3; j++)457{458if (Dist2 (*tet[j], *tri[i]) < eps2)459{460cnt++;461tetp2 = tetp1;462tetp1 = j;463trip2 = trip1;464trip1 = i;465break;466}467}468}469}470else471*/472{473for (i = 0; i <= 2; i++)474{475for (j = 0; j <= 3; j++)476{477if (tetpi[j] == tripi[i])478{479cnt++;480tetp2 = tetp1;481tetp1 = j;482trip2 = trip1;483trip1 = i;484break;485}486}487}488}489490// (*testout) << "cnt = " << cnt << endl;491492493switch (cnt)494{495case 0:496{497Vec3d no, n;498// int inpi[3];499int pside[3][4];500501for (j = 0; j < 3; j++)502{503pside[j][0] = (*tri[j])(0) > -eps;504pside[j][1] = (*tri[j])(1) > -eps;505pside[j][2] = (*tri[j])(2) > -eps;506pside[j][3] = (*tri[j])(0) + (*tri[j])(1) + (*tri[j])(2) < 1+eps;507}508509510for (j = 0; j < 4; j++)511{512if (!pside[0][j] && !pside[1][j] && !pside[2][j])513return 0;514}515516for (j = 0; j < 3; j++)517{518if (pside[j][0] && pside[j][1] && pside[j][2] && pside[j][3])519return 1;520}521522523const Point<3> * line[2], *tetf[3];524for (i = 0; i <= 2; i++)525for (j = i+1; j <= 3; j++)526{527line[0] = tet[i];528line[1] = tet[j];529530if (IntersectTriangleLine (tri, &line[0]))531return 1;532}533534for (i = 0; i <= 3; i++)535{536for (j = 0; j <= 2; j++)537tetf[j] = tet[(i+j) % 4];538539for (j = 0; j <= 2; j++)540{541line[0] = tri[j];542line[1] = tri[(j+1) % 3];543544if (IntersectTriangleLine (&tetf[0], &line[0]))545return 1;546}547}548549550return 0;551break;552}553case 1:554{555trip2 = 0;556if (trip2 == trip1)557trip2++;558trip3 = 3 - trip1 - trip2;559560tetp2 = 0;561while (tetp2 == tetp1)562tetp2++;563tetp3 = 0;564while (tetp3 == tetp1 || tetp3 == tetp2)565tetp3++;566tetp4 = 6 - tetp1 - tetp2 - tetp3;567568Vec3d vtri1 = *tri[trip2] - *tri[trip1];569Vec3d vtri2 = *tri[trip3] - *tri[trip1];570Vec3d ntri;571Cross (vtri1, vtri2, ntri);572573// tri durch tet ?574575/*576Vec3d vtet1(*tet[tetp1], *tet[tetp2]);577Vec3d vtet2(*tet[tetp1], *tet[tetp3]);578Vec3d vtet3(*tet[tetp1], *tet[tetp4]);579Vec3d sol;580581SolveLinearSystem (vtet1, vtet2, vtet3, vtri1, sol);582if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0)583return 1;584585SolveLinearSystem (vtet1, vtet2, vtet3, vtri2, sol);586if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0)587return 1;588*/589590// test 3 tet-faces:591for (i = 1; i <= 3; i++)592{593Vec3d vtet1, vtet2;594switch (i)595{596case 1:597{598vtet1 = *tet[tetp2] - *tet[tetp1];599vtet2 = *tet[tetp3] - *tet[tetp1];600break;601}602case 2:603{604vtet1 = *tet[tetp3] - *tet[tetp1];605vtet2 = *tet[tetp4] - *tet[tetp1];606break;607}608case 3:609{610vtet1 = *tet[tetp4] - *tet[tetp1];611vtet2 = *tet[tetp2] - *tet[tetp1];612break;613}614}615616Vec3d ntet;617Cross (vtet1, vtet2, ntet);618619Vec3d crline = Cross (ntri, ntet);620621double lcrline = crline.Length();622if (lcrline < eps * eps)623continue;624625626if (vtri1 * crline + vtri2 * crline < 0)627crline *= -1;628629double lam1, lam2, lam3, lam4;630LocalCoordinates (vtri1, vtri2, crline, lam1, lam2);631LocalCoordinates (vtet1, vtet2, crline, lam3, lam4);632633if (lam1 > -eps && lam2 > -eps &&634lam3 > -eps && lam4 > -eps)635{636// (*testout) << "hit, cnt == 1" << "\n";637return 1;638}639}640641return 0;642break;643}644case 2:645{646// common edge647tetp3 = 0;648while (tetp3 == tetp1 || tetp3 == tetp2)649tetp3++;650tetp4 = 6 - tetp1 - tetp2 - tetp3;651trip3 = 3 - trip1 - trip2;652653// (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl;654// (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2655// << ", " << tetp3 << ", " << tetp4 << endl;656657Vec3d vtri = *tri[trip3] - *tri[trip1];658Vec3d vtet1 = *tet[tetp3] - *tri[trip1];659Vec3d vtet2 = *tet[tetp4] - *tri[trip1];660661Vec3d n = *tri[trip2] - *tri[trip1];662n /= n.Length();663664vtet1 -= (n * vtet1) * n;665vtet2 -= (n * vtet2) * n;666667668double lam1, lam2;669LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2);670671if (lam1 < -eps || lam2 < -eps)672return 0;673else674{675676// (*testout) << "vtet1 = " << vtet1 << endl;677// (*testout) << "vtet2 = " << vtet2 << endl;678// (*testout) << "vtri = " << vtri << endl;679// (*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl;680681// (*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2))682// << " = " << (vtet1 * vtri) << endl;683// (*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2))684// << " = " << (vtet2 * vtri) << endl;685686// (*testout) << "tet = ";687// for (j = 0; j < 4; j++)688// (*testout) << (*tet[j]) << " ";689// (*testout) << endl;690// (*testout) << "tri = ";691// for (j = 0; j < 3; j++)692// (*testout) << (*tri[j]) << " ";693// (*testout) << endl;694695// (*testout) << "hit, cnt == 2" << endl;696697return 1;698}699700break;701}702case 3:703{704// common face705return 0;706}707}708709(*testout) << "hit, cnt = " << cnt << endl;710return 1;711}712713714715716717718719720721722723int IntersectTriangleTriangle (const Point<3> ** tri1, const Point<3> ** tri2)724{725int i, j;726double diam = Dist (*tri1[0], *tri1[1]);727double epsrel = 1e-8;728double eps = diam * epsrel;729double eps2 = eps * eps;730731732733int cnt = 0;734/*735int tri1pi[3];736int tri2pi[3];737*/738739// int tri1p1 = -1;740/// int tri1p2 = -1;741// int tri2p1 = -1;742// int tri2p2 = -1;743// int tri1p3, tri2p3;744745/*746for (i = 0; i < 3; i++)747tri1pi[i] = -1;748*/749for (i = 0; i <= 2; i++)750{751// tri2pi[i] = -1;752for (j = 0; j <= 2; j++)753{754if (Dist2 (*tri1[j], *tri2[i]) < eps2)755{756// tri2pi[i] = j;757// tri1pi[j] = i;758cnt++;759// tri1p2 = tri1p1;760// tri1p1 = j;761// tri2p2 = tri2p1;762// tri2p1 = i;763break;764}765}766}767768switch (cnt)769{770case 0:771{772const Point<3> * line[2];773774for (i = 0; i <= 2; i++)775{776line[0] = tri2[i];777line[1] = tri2[(i+1)%3];778779if (IntersectTriangleLine (tri1, &line[0]))780{781(*testout) << "int1, line = " << *line[0] << " - " << *line[1] << endl;782return 1;783}784}785786for (i = 0; i <= 2; i++)787{788line[0] = tri1[i];789line[1] = tri1[(i+1)%3];790791if (IntersectTriangleLine (tri2, &line[0]))792{793(*testout) << "int2, line = " << *line[0] << " - " << *line[1] << endl;794return 1;795}796}797break;798}799default:800return 0;801}802803return 0;804}805806807808void809LocalCoordinates (const Vec3d & e1, const Vec3d & e2,810const Vec3d & v, double & lam1, double & lam2)811{812double m11 = e1 * e1;813double m12 = e1 * e2;814double m22 = e2 * e2;815double rs1 = v * e1;816double rs2 = v * e2;817818double det = m11 * m22 - m12 * m12;819lam1 = (rs1 * m22 - rs2 * m12)/det;820lam2 = (m11 * rs2 - m12 * rs1)/det;821}822823824825826827int CalcSphereCenter (const Point<3> ** pts, Point<3> & c)828{829Vec3d row1 (*pts[0], *pts[1]);830Vec3d row2 (*pts[0], *pts[2]);831Vec3d row3 (*pts[0], *pts[3]);832833Vec3d rhs(0.5 * (row1*row1),8340.5 * (row2*row2),8350.5 * (row3*row3));836Transpose (row1, row2, row3);837838Vec3d sol;839if (SolveLinearSystem (row1, row2, row3, rhs, sol))840{841(*testout) << "CalcSphereCenter: degenerated" << endl;842return 1;843}844845c = *pts[0] + sol;846return 0;847}848849850851852853int CalcTriangleCenter (const Point3d ** pts, Point3d & c)854{855static DenseMatrix a(2), inva(2);856static Vector rs(2), sol(2);857double h = Dist(*pts[0], *pts[1]);858859Vec3d v1(*pts[0], *pts[1]);860Vec3d v2(*pts[0], *pts[2]);861862rs.Elem(1) = v1 * v1;863rs.Elem(2) = v2 * v2;864865a.Elem(1,1) = 2 * rs.Get(1);866a.Elem(1,2) = a.Elem(2,1) = 2 * (v1 * v2);867a.Elem(2,2) = 2 * rs.Get(2);868869if (fabs (a.Det()) <= 1e-12 * h * h)870{871(*testout) << "CalcTriangleCenter: degenerated" << endl;872return 1;873}874875CalcInverse (a, inva);876inva.Mult (rs, sol);877878c = *pts[0];879v1 *= sol.Get(1);880v2 *= sol.Get(2);881882c += v1;883c += v2;884885return 0;886}887888889890double ComputeCylinderRadius (const Point3d & p1,891const Point3d & p2,892const Point3d & p3,893const Point3d & p4)894{895Vec3d v12(p1, p2);896Vec3d v13(p1, p3);897Vec3d v14(p1, p4);898899Vec3d n1 = Cross (v12, v13);900Vec3d n2 = Cross (v14, v12);901902double n1l = n1.Length();903double n2l = n2.Length();904n1 /= n1l;905n2 /= n2l;906907double v12len = v12.Length();908double h1 = n1l / v12len;909double h2 = n2l / v12len;910911/*912(*testout) << "n1 = " << n1 << " n2 = " << n2913<< "h1 = " << h1 << " h2 = " << h2 << endl;914*/915return ComputeCylinderRadius (n1, n2, h1, h2);916}917918919920921/*922Two triangles T1 and T2 have normals n1 and n2.923The height over the common edge is h1, and h2.924*/925double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2,926double h1, double h2)927{928Vec3d t1, t2;929double n11 = n1 * n1;930double n12 = n1 * n2;931double n22 = n2 * n2;932double det = n11 * n22 - n12 * n12;933934if (fabs (det) < 1e-14 * n11 * n22)935return 1e20;936937// a biorthogonal bases (ti * nj) = delta_ij:938t1 = (n22/det) * n1 + (-n12/det) * n2;939t2 = (-n12/det) * n1 + (n11/det) * n2;940941// normalize:942t1 /= t1.Length();943t2 /= t2.Length();944945/*946vector to center point has form947v = lam1 n1 + lam2 n2948and fulfills949t2 v = h1/2950t1 v = h2/2951*/952953double lam1 = 0.5 * h2 / (n1 * t1);954double lam2 = 0.5 * h1 / (n2 * t2);955956double rad = (lam1 * n1 + lam2 * n2).Length();957/*958(*testout) << "n1 = " << n1959<< " n2 = " << n2960<< " t1 = " << t1961<< " t2 = " << t2962<< " rad = " << rad << endl;963*/964return rad;965}966967968969970971972double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p)973{974Vec2d v(lp1, lp2);975Vec2d vlp(lp1, p);976977// dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^2978979// lam = (v * vlp) / (v * v);980// if (lam < 0) lam = 0;981// if (lam > 1) lam = 1;982983double num = v*vlp;984double den = v*v;985986if (num <= 0)987return Dist2 (lp1, p);988989if (num >= den)990return Dist2 (lp2, p);991992if (den > 0)993{994return vlp.Length2() - num * num /den;995}996else997return vlp.Length2();998}9991000100110021003double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p)1004{1005Vec3d v(lp1, lp2);1006Vec3d vlp(lp1, p);10071008// dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^210091010// lam = (v * vlp) / (v * v);1011// if (lam < 0) lam = 0;1012// if (lam > 1) lam = 1;10131014double num = v*vlp;1015double den = v*v;10161017if (num <= 0)1018return Dist2 (lp1, p);10191020if (num >= den)1021return Dist2 (lp2, p);10221023if (den > 0)1024{1025return vlp.Length2() - num * num /den;1026}1027else1028return vlp.Length2();1029}1030103110321033double MinDistTP2 (const Point3d & tp1, const Point3d & tp2,1034const Point3d & tp3, const Point3d & p)1035{1036double lam1, lam2;1037double res;10381039LocalCoordinates (Vec3d (tp1, tp2), Vec3d (tp1, tp3),1040Vec3d (tp1, p), lam1, lam2);1041int in1 = lam1 >= 0;1042int in2 = lam2 >= 0;1043int in3 = lam1+lam2 <= 1;10441045if (in1 && in2 && in3)1046{1047Point3d pp = tp1 + lam1 * Vec3d(tp1, tp2) + lam2 * Vec3d (tp1, tp3);1048res = Dist2 (p, pp);1049}1050else1051{1052res = Dist2 (tp1, p);1053if (!in1)1054{1055double hv = MinDistLP2 (tp1, tp3, p);1056if (hv < res) res = hv;1057}1058if (!in2)1059{1060double hv = MinDistLP2 (tp1, tp2, p);1061if (hv < res) res = hv;1062}1063if (!in3)1064{1065double hv = MinDistLP2 (tp2, tp3, p);1066if (hv < res) res = hv;1067}1068/*1069double d1 = MinDistLP2 (tp1, tp2, p);1070double d2 = MinDistLP2 (tp1, tp3, p);1071double d3 = MinDistLP2 (tp2, tp3, p);1072res = min3 (d1, d2, d3);1073*/1074}10751076return res;10771078Vec3d pp1(tp1, p);1079Vec3d v1(tp1, tp2), v2(tp1, tp3);10801081double c = pp1.Length2();1082double cx = -2 * (pp1 * v1);1083double cy = -2 * (pp1 * v2);1084double cxx = v1.Length2();1085double cxy = 2 * (v1 * v2);1086double cyy = v2.Length2();10871088QuadraticPolynomial2V pol (-c, -cx, -cy, -cxx, -cxy, -cyy);1089double res2 = - pol.MaxUnitTriangle ();10901091if (fabs (res - res2) > 1e-8)1092cout << "res and res2 differ: " << res << " != " << res2 << endl;1093return res2;1094}109510961097// 0 checks !!!1098double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2,1099const Point3d & l2p1, const Point3d & l2p2)1100{1101// dist(lam1,lam2) = \| l2p1+lam2v2 - (l1p1+lam1 v1) \|1102// min !11031104Vec3d l1l2 (l1p1, l2p1);1105Vec3d v1 (l1p1, l1p2);1106Vec3d v2 (l2p1, l2p2);11071108double a11, a12, a22, rs1, rs2;1109double lam1, lam2, det;11101111a11 = v1*v1;1112a12 = -(v1*v2);1113a22 = v2*v2;1114rs1 = l1l2 * v1;1115rs2 = - (l1l2 * v2);11161117det = a11 * a22 - a12 * a12;1118if (det < 1e-14 * a11 * a22)1119det = 1e-14 * a11 * a22; // regularization should be stable11201121if (det < 1e-20)1122det = 1e-20;112311241125lam1 = (a22 * rs1 - a12 * rs2) / det;1126lam2 = (-a12 * rs1 + a11 * rs2) / det;11271128if (lam1 >= 0 && lam2 >= 0 && lam1 <= 1 && lam2 <= 1)1129{1130Vec3d v = l1l2 + (-lam1) * v1 + lam2 * v2;1131return v.Length2();1132}11331134double minv, hv;1135minv = MinDistLP2 (l1p1, l1p2, l2p1);1136hv = MinDistLP2 (l1p1, l1p2, l2p2);1137if (hv < minv) minv = hv;11381139hv = MinDistLP2 (l2p1, l2p2, l1p1);1140if (hv < minv) minv = hv;1141hv = MinDistLP2 (l2p1, l2p2, l1p2);1142if (hv < minv) minv = hv;11431144return minv;1145}11461147}11481149115011511152