Path: blob/devel/ElmerGUI/netgen/libsrc/geom2d/spline2d.cpp
3206 views
12d Spline curve for Mesh generator234OLD IMPLEMENTATION, NOT USED ANYMORE!5678#include <mystdlib.h>9#include <csg.hpp>10#include <linalg.hpp>11#include <meshing.hpp>1213namespace netgen14{15#include "spline2d.hpp"161718void CalcPartition (double l, double h, double r1, double r2,19double ra, double elto0, ARRAY<double> & points);20212223// calculates length of spline-curve24double SplineSegment :: Length () const25{26Point<2> p, pold;2728int i, n = 100;29double dt = 1.0 / n;3031pold = GetPoint (0);3233double l = 0;34for (i = 1; i <= n; i++)35{36p = GetPoint (i * dt);37l += Dist (p, pold);38pold = p;39}40return l;41}42434445// partitionizes spline curve46void SplineSegment :: Partition (double h, double elto0,47Mesh & mesh, Point3dTree & searchtree, int segnr) const48{49int i, j;50double l, r1, r2, ra;51double lold, dt, frac;52int n = 100;53Point<2> p, pold, mark, oldmark;54ARRAY<double> curvepoints;55double edgelength, edgelengthold;56l = Length();5758r1 = StartPI().refatpoint;59r2 = EndPI().refatpoint;60ra = reffak;6162// cout << "Partition, l = " << l << ", h = " << h << endl;63CalcPartition (l, h, r1, r2, ra, elto0, curvepoints);64// cout << "curvepoints = " << curvepoints << endl;6566dt = 1.0 / n;6768l = 0;69j = 1;7071pold = GetPoint (0);72lold = 0;73oldmark = pold;74edgelengthold = 0;75ARRAY<int> locsearch;7677for (i = 1; i <= n; i++)78{79p = GetPoint (i*dt);80l = lold + Dist (p, pold);81while (j < curvepoints.Size() && (l >= curvepoints[j] || i == n))82{83frac = (curvepoints[j]-lold) / (l-lold);84mark = pold + frac * (p-pold);85edgelength = i*dt + (frac-1)*dt;86{87PointIndex pi1 = -1, pi2 = -1;8889Point3d mark3(mark(0), mark(1), 0);90Point3d oldmark3(oldmark(0), oldmark(1), 0);9192Vec<3> v (1e-4*h, 1e-4*h, 1e-4*h);93searchtree.GetIntersecting (oldmark3 - v, oldmark3 + v, locsearch);94if (locsearch.Size()) pi1 = locsearch[0];9596searchtree.GetIntersecting (mark3 - v, mark3 + v, locsearch);97if (locsearch.Size()) pi2 = locsearch[0];98/*99for (PointIndex pk = PointIndex::BASE;100pk < mesh.GetNP()+PointIndex::BASE; pk++)101{102if (Dist (mesh[pk], oldmark3) < 1e-4 * h) pi1 = pk;103if (Dist (mesh[pk], mark3) < 1e-4 * h) pi2 = pk;104}105*/106107108// cout << "pi1 = " << pi1 << endl;109// cout << "pi2 = " << pi2 << endl;110111if (pi1 == -1)112{113pi1 = mesh.AddPoint(oldmark3);114searchtree.Insert (oldmark3, pi1);115}116if (pi2 == -1)117{118pi2 = mesh.AddPoint(mark3);119searchtree.Insert (mark3, pi2);120}121122// cout << "pi1 = " << pi1 << endl;123// cout << "pi2 = " << pi2 << endl;124125Segment seg;126seg.edgenr = segnr;127seg.si = bc; // segnr;128seg.p1 = pi1;129seg.p2 = pi2;130seg.domin = leftdom;131seg.domout = rightdom;132seg.epgeominfo[0].edgenr = segnr;133seg.epgeominfo[0].dist = edgelengthold;134seg.epgeominfo[1].edgenr = segnr;135seg.epgeominfo[1].dist = edgelength;136seg.singedge_left = hpref_left;137seg.singedge_right = hpref_right;138mesh.AddSegment (seg);139}140141oldmark = mark;142edgelengthold = edgelength;143j++;144}145146pold = p;147lold = l;148}149}150151152void SplineSegment :: GetPoints (int n, ARRAY<Point<2> > & points)153{154points.SetSize (n);155if (n >= 2)156for (int i = 0; i < n; i++)157points[i] = GetPoint(double(i) / (n-1));158}159160void SplineSegment :: PrintCoeff (ostream & ost) const161{162Vector u(6);163164GetCoeff(u);165166for ( int i=0; i<6; i++)167ost << u[i] << " ";168ost << endl;169}170171172173/*174Implementation of line-segment from p1 to p2175*/176177178LineSegment :: LineSegment (const GeomPoint2d & ap1,179const GeomPoint2d & ap2)180: p1(ap1), p2(ap2)181{182;183}184185186Point<2> LineSegment :: GetPoint (double t) const187{188return p1 + t * (p2 - p1);189}190191double LineSegment :: Length () const192{193return Dist (p1, p2);194}195196197void LineSegment :: GetCoeff (Vector & coeffs) const198{199coeffs.SetSize(6);200201double dx = p2(0) - p1(0);202double dy = p2(1) - p1(1);203204coeffs[0] = coeffs[1] = coeffs[2] = 0;205coeffs[3] = dy;206coeffs[4] = -dx;207coeffs[5] = dx * p1(1) - dy * p1(0);208}209210211212void LineSegment :: LineIntersections (const double a, const double b, const double c,213ARRAY < Point<2> > & points, const double eps) const214{215points.SetSize(0);216217double denom = -a*p2(0)+a*p1(0)-b*p2(1)+b*p1(1);218if(fabs(denom) < 1e-20)219return;220221double t = (a*p1(0)+b*p1(1)+c)/denom;222if((t > -eps) && (t < 1.+eps))223points.Append(GetPoint(t));224}225226227SplineSegment3 :: SplineSegment3 (const GeomPoint2d & ap1,228const GeomPoint2d & ap2,229const GeomPoint2d & ap3)230: p1(ap1), p2(ap2), p3(ap3)231{232;233}234235Point<2> SplineSegment3 :: GetPoint (double t) const236{237double x, y, w;238double b1, b2, b3;239240b1 = (1-t)*(1-t);241b2 = sqrt(2.0) * t * (1-t);242b3 = t * t;243244x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3;245y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3;246w = b1 + b2 + b3;247248return Point<2> (x/w, y/w);249}250251252void SplineSegment3 :: GetCoeff (Vector & u) const253{254double t;255int i;256Point<2> p;257DenseMatrix a(6, 6);258DenseMatrix ata(6, 6);259Vector f(6);260261u.SetSize(6);262263// ata.SetSymmetric(1);264265t = 0;266for (i = 1; i <= 5; i++, t += 0.25)267{268p = GetPoint (t);269a.Elem(i, 1) = p(0) * p(0);270a.Elem(i, 2) = p(1) * p(1);271a.Elem(i, 3) = p(0) * p(1);272a.Elem(i, 4) = p(0);273a.Elem(i, 5) = p(1);274a.Elem(i, 6) = 1;275}276a.Elem(6, 1) = 1;277278CalcAtA (a, ata);279280u = 0;281u.Elem(6) = 1;282a.MultTrans (u, f);283ata.Solve (f, u);284}285286double SplineSegment3 :: MaxCurvature(void) const287{288Vec<2> v1 = p1-p2;289Vec<2> v2 = p3-p2;290double l1 = v1.Length();291double l2 = v2.Length();292293double cosalpha = v1*v2/(l1*l2);294295296return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));297}298299300void SplineSegment3 :: LineIntersections (const double a, const double b, const double c,301ARRAY < Point<2> > & points, const double eps) const302{303points.SetSize(0);304305double t;306307const double c1 = a*p1(0) - sqrt(2.)*a*p2(0) + a*p3(0)308+ b*p1(1) - sqrt(2.)*b*p2(1) + b*p3(1)309+ (2.-sqrt(2.))*c;310const double c2 = -2.*a*p1(0) + sqrt(2.)*a*p2(0) -2.*b*p1(1) + sqrt(2.)*b*p2(1) + (sqrt(2.)-2.)*c;311const double c3 = a*p1(0) + b*p1(1) + c;312313if(fabs(c1) < 1e-20)314{315if(fabs(c2) < 1e-20)316return;317318t = -c3/c2;319if((t > -eps) && (t < 1.+eps))320points.Append(GetPoint(t));321return;322}323324const double D = c2*c2-4.*c1*c3;325326if(D < 0)327return;328329if(fabs(D/(c1*c1)) < 1e-14)330{331t = -0.5*c2/c1;332if((t > -eps) && (t < 1.+eps))333points.Append(GetPoint(t));334return;335}336337t = (-c2 + sqrt(D))/(2.*c1);338if((t > -eps) && (t < 1.+eps))339points.Append(GetPoint(t));340341t = (-c2 - sqrt(D))/(2.*c1);342if((t > -eps) && (t < 1.+eps))343points.Append(GetPoint(t));344}345346347348//########################################################################349// circlesegment350351CircleSegment :: CircleSegment (const GeomPoint2d & ap1,352const GeomPoint2d & ap2,353const GeomPoint2d & ap3)354: p1(ap1), p2(ap2), p3(ap3)355{356Vec<2> v1,v2;357358v1 = p1 - p2;359v2 = p3 - p2;360361Point<2> p1t(p1(0)+v1[1], p1(1)-v1[0]);362Point<2> p2t(p3(0)+v2[1], p3(1)-v2[0]);363Line2d g1t(p1, p1t), g2t(p3, p2t);364365pm = CrossPoint (g1t,g2t);366radius = Dist(pm,StartPI());367w1 = Angle(Vec2d (p1 - pm));368w3 = Angle(Vec2d (p3 - pm));369if ( fabs(w3-w1) > M_PI )370{371if ( w3>M_PI ) w3 -= 2*M_PI;372if ( w1>M_PI ) w1 -= 2*M_PI;373}374}375376Point<2> CircleSegment :: GetPoint (double t) const377{378if (t >= 1.0) { return p3; }379380double phi = StartAngle() + t*(EndAngle()-StartAngle());381Vec2d tmp(cos(phi),sin(phi));382383return pm + Radius()*tmp;384}385386void CircleSegment :: GetCoeff (Vector & coeff) const387{388coeff[0] = coeff[1] = 1.0;389coeff[2] = 0.0;390coeff[3] = -2.0 * pm[0];391coeff[4] = -2.0 * pm[1];392coeff[5] = sqr(pm[0]) + sqr(pm[1]) - sqr(Radius());393}394395396void CircleSegment :: LineIntersections (const double a, const double b, const double c,397ARRAY < Point<2> > & points, const double eps) const398{399points.SetSize(0);400401double px=0,py=0;402403if(fabs(b) > 1e-20)404py = -c/b;405else406px = -c/a;407408const double c1 = a*a + b*b;409const double c2 = 2. * ( a*(py-pm(1)) - b*(px-pm(0)));410const double c3 = pow(px-pm(0),2) + pow(py-pm(1),2) - pow(Radius(),2);411412const double D = c2*c2 - 4*c1*c3;413414if(D < 0)415return;416417ARRAY<double> t;418419if(fabs(D) < 1e-20)420t.Append(-0.5*c2/c1);421else422{423t.Append((-c2+sqrt(D))/(2.*c1));424t.Append((-c2-sqrt(D))/(2.*c1));425}426427for(int i=0; i<t.Size(); i++)428{429Point<2> p (px-t[i]*b,py+t[i]*a);430431double angle = atan2(p(1),p(0))+M_PI;432433if(angle > StartAngle()-eps && angle < EndAngle()+eps)434points.Append(p);435}436}437438439440DiscretePointsSegment :: DiscretePointsSegment (const ARRAY<Point<2> > & apts)441: pts (apts),442p1 (apts[0](0), apts[0](1), 1),443p2 (apts.Last()(0), apts.Last()(1), 1)444445{ ; }446447448DiscretePointsSegment :: ~DiscretePointsSegment ()449{ ; }450451Point<2> DiscretePointsSegment :: GetPoint (double t) const452{453double t1 = t * (pts.Size()-1);454int segnr = int(t1);455if (segnr < 0) segnr = 0;456if (segnr >= pts.Size()) segnr = pts.Size()-1;457458double rest = t1 - segnr;459460return Point<2> ((1-rest)*pts[segnr](0) + rest*pts[segnr+1](0),461(1-rest)*pts[segnr](1) + rest*pts[segnr+1](1));462}463464465466467468469//########################################################################470471472473474void CalcPartition (double l, double h, double r1, double r2,475double ra, double elto0, ARRAY<double> & points)476{477int i, j, n, nel;478double sum, t, dt, fun, fperel, oldf, f;479480n = 1000;481482points.SetSize (0);483484sum = 0;485dt = l / n;486t = 0.5 * dt;487for (i = 1; i <= n; i++)488{489fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);490sum += dt / fun;491t += dt;492}493494nel = int (sum+1);495fperel = sum / nel;496497points.Append (0);498499i = 1;500oldf = 0;501t = 0.5 * dt;502for (j = 1; j <= n && i < nel; j++)503{504fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);505506f = oldf + dt / fun;507508while (f > i * fperel && i < nel)509{510points.Append ( (l/n) * (j-1 + (i * fperel - oldf) / (f - oldf)) );511i++;512}513oldf = f;514t += dt;515}516points.Append (l);517}518519520}521522523