Path: blob/devel/ElmerGUI/netgen/libsrc/geom2d/spline.cpp
3206 views
/*12Spline curve for Mesh generator34*/56#include <mystdlib.h>7#include <csg.hpp>8#include <linalg.hpp>9#include <meshing.hpp>1011namespace netgen12{13#include "spline.hpp"1415/*16template<> void SplineSeg3<2> :: Project (const Point<2> point, Point<2> & point_on_curve, double & t) const17{18double t_old = 0;19t = 0.5;2021Point<2> phi;22Vec<2> phip,phipp,phimp;2324int i=0;2526while(fabs(t-t_old) > 1e-8 && i<10)27{28GetDerivatives(t,phi,phip,phipp);2930t_old = t;3132phimp = phi-point;3334t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);3536i++;37}3839if(i<10)40{41point_on_curve = GetPoint(t);4243double dist = Dist(point,point_on_curve);4445phi = GetPoint(0);46double auxdist = Dist(phi,point);47if(auxdist < dist)48{49t = 0.;50point_on_curve = phi;51dist = auxdist;52}53phi = GetPoint(1);54auxdist = Dist(phi,point);55if(auxdist < dist)56{57t = 1.;58point_on_curve = phi;59dist = auxdist;60}6162}63else64{65double t0 = 0;66double t1 = 0.5;67double t2 = 1.;6869double d0,d1,d2;707172//(*testout) << "2d newtonersatz" << endl;73while(t2-t0 > 1e-8)74{7576phi = GetPoint(t0); d0 = Dist(phi,point);77phi = GetPoint(t1); d1 = Dist(phi,point);78phi = GetPoint(t2); d2 = Dist(phi,point);7980double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);8182if(a <= 0)83{84if(d0 < d2)85t2 -= 0.3*(t2-t0);86else87t0 += 0.3*(t2-t0);8889t1 = 0.5*(t2+t0);90}91else92{93double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);9495double auxt1 = -0.5*b/a;9697if(auxt1 < t0)98{99t2 -= 0.4*(t2-t0);100t0 = max2(0.,t0-0.1*(t2-t0));101}102else if (auxt1 > t2)103{104t0 += 0.4*(t2-t0);105t2 = min2(1.,t2+0.1*(t2-t0));106}107else108{109t1 = auxt1;110auxt1 = 0.25*(t2-t0);111t0 = max2(0.,t1-auxt1);112t2 = min2(1.,t1+auxt1);113}114115t1 = 0.5*(t2+t0);116}117118}119120121phi = GetPoint(t0); d0 = Dist(phi,point);122phi = GetPoint(t1); d1 = Dist(phi,point);123phi = GetPoint(t2); d2 = Dist(phi,point);124125double mind = d0;126t = t0;127if(d1 < mind)128{129t = t1;130mind = d1;131}132if(d2 < mind)133{134t = t2;135mind = d2;136}137138point_on_curve = GetPoint(t);139140}141}142143template<> void SplineSeg3<3> :: Project (const Point<3> point, Point<3> & point_on_curve, double & t) const144{145double t_old = -1;146147if(proj_latest_t > 0. && proj_latest_t < 1.)148t = proj_latest_t;149else150t = 0.5;151152Point<3> phi;153Vec<3> phip,phipp,phimp;154155int i=0;156157while(fabs(t-t_old) > 1e-8 && t > -0.5 && t < 1.5 && i<10)158{159GetDerivatives(t,phi,phip,phipp);160161t_old = t;162163phimp = phi-point;164165//t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);166t -= (phip*phimp)/(phipp*phimp + phip*phip);167168i++;169}170171//if(i<10 && t > 0. && t < 1.)172if(i<10 && t > -0.4 && t < 1.4)173{174if(t < 0)175t = 0.;176if(t > 1)177t = 1.;178179point_on_curve = GetPoint(t);180181double dist = Dist(point,point_on_curve);182183phi = GetPoint(0);184double auxdist = Dist(phi,point);185if(auxdist < dist)186{187t = 0.;188point_on_curve = phi;189dist = auxdist;190}191phi = GetPoint(1);192auxdist = Dist(phi,point);193if(auxdist < dist)194{195t = 1.;196point_on_curve = phi;197dist = auxdist;198}199}200else201{202double t0 = 0;203double t1 = 0.5;204double t2 = 1.;205206double d0,d1,d2;207208209//(*testout) << "newtonersatz" << endl;210while(t2-t0 > 1e-8)211{212213phi = GetPoint(t0); d0 = Dist(phi,point);214phi = GetPoint(t1); d1 = Dist(phi,point);215phi = GetPoint(t2); d2 = Dist(phi,point);216217double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);218219if(a <= 0)220{221if(d0 < d2)222t2 -= 0.3*(t2-t0);223else224t0 += 0.3*(t2-t0);225226t1 = 0.5*(t2+t0);227}228else229{230double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);231232double auxt1 = -0.5*b/a;233234if(auxt1 < t0)235{236t2 -= 0.4*(t2-t0);237t0 = max2(0.,t0-0.1*(t2-t0));238}239else if (auxt1 > t2)240{241t0 += 0.4*(t2-t0);242t2 = min2(1.,t2+0.1*(t2-t0));243}244else245{246t1 = auxt1;247auxt1 = 0.25*(t2-t0);248t0 = max2(0.,t1-auxt1);249t2 = min2(1.,t1+auxt1);250}251252t1 = 0.5*(t2+t0);253}254255}256257258phi = GetPoint(t0); d0 = Dist(phi,point);259phi = GetPoint(t1); d1 = Dist(phi,point);260phi = GetPoint(t2); d2 = Dist(phi,point);261262double mind = d0;263t = t0;264if(d1 < mind)265{266t = t1;267mind = d1;268}269if(d2 < mind)270{271t = t2;272mind = d2;273}274275point_on_curve = GetPoint(t);276}277//(*testout) << " latest_t " << proj_latest_t << " t " << t << endl;278279proj_latest_t = t;280}281*/282283void CalcPartition (double l, double h, double r1, double r2,284double ra, double elto0, ARRAY<double> & points)285{286int i, j, n, nel;287double sum, t, dt, fun, fperel, oldf, f;288289n = 1000;290291points.SetSize (0);292293sum = 0;294dt = l / n;295t = 0.5 * dt;296for (i = 1; i <= n; i++)297{298fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);299sum += dt / fun;300t += dt;301}302303nel = int (sum+1);304fperel = sum / nel;305306points.Append (0);307308i = 1;309oldf = 0;310t = 0.5 * dt;311for (j = 1; j <= n && i < nel; j++)312{313fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);314315f = oldf + dt / fun;316317while (f > i * fperel && i < nel)318{319points.Append ( (l/n) * (j-1 + (i * fperel - oldf) / (f - oldf)) );320i++;321}322oldf = f;323t += dt;324}325points.Append (l);326}327328template<>329double SplineSeg3<2> :: MaxCurvature(void) const330{331Vec<2> v1 = p1-p2;332Vec<2> v2 = p3-p2;333double l1 = v1.Length();334double l2 = v2.Length();335336double cosalpha = (v1*v2)/(l1*l2);337338339return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));340}341342template<>343double SplineSeg3<3> :: MaxCurvature(void) const344{345Vec<3> v1 = p1-p2;346Vec<3> v2 = p3-p2;347double l1 = v1.Length();348double l2 = v2.Length();349350double cosalpha = v1*v2/(l1*l2);351352353return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));354}355356357358359}360361362