Path: blob/devel/ElmerGUI/netgen/libsrc/csg/bspline2d.cpp
3206 views
#include <mystdlib.h>12#include <csg.hpp>34namespace netgen5{67BSplineCurve2d :: BSplineCurve2d ()8{9redlevel = 0;10}111213void BSplineCurve2d :: AddPoint (const Point<2> & apoint)14{15points.Append (apoint);16intervallused.Append (0);17}1819bool BSplineCurve2d :: Inside (const Point<2> & p, double & dist) const20{21Point<2> hp = p;22double t = ProjectParam (p);23hp = Eval(t);24Vec<2> v = EvalPrime (t);2526Vec<2> n (v(0), -v(1));2728cout << "p = " << p << ", hp = " << hp << endl;29dist = Dist (p, hp);30double scal = (hp-p) * n;31cout << "scal = " << scal << endl;3233return scal >= 0;34}3536double BSplineCurve2d :: ProjectParam (const Point<2> & p) const37{38double t, dt, mindist, mint = 0.0;39int n1;4041mindist = 1e10;42dt = 0.2;43for (n1 = 1; n1 <= points.Size(); n1++)44if (intervallused.Get(n1) == 0)45for (t = n1; t <= n1+1; t += dt)46if (Dist (Eval(t), p) < mindist)47{48mint = t;49mindist = Dist (Eval(t), p);50}5152if (mindist > 1e9)53{54for (t = 0; t <= points.Size(); t += dt)55if (Dist (Eval(t), p) < mindist)56{57mint = t;58mindist = Dist (Eval(t), p);59}60}6162while (Dist (Eval (mint-dt), p) < mindist)63{64mindist = Dist (Eval (mint-dt), p);65mint -= dt;66}67while (Dist (Eval (mint+dt), p) < mindist)68{69mindist = Dist (Eval (mint+dt), p);70mint += dt;71}727374return NumericalProjectParam (p, mint-dt, mint+dt);75}767778// t \in (n1, n2)7980Point<2> BSplineCurve2d :: Eval (double t) const81{82int n, n1, n2, n3, n4;83double loct, b1, b2, b3, b4;84Point<2> hp;8586static int cnt = 0;87cnt++;88if (cnt % 100000 == 0) (*mycout) << "cnt = " << cnt << endl;8990n = int(t);91loct = t - n;9293b1 = 0.25 * (1 - loct) * (1 - loct);94b4 = 0.25 * loct * loct;95b2 = 0.5 - b4;96b3 = 0.5 - b1;9798n1 = (n + 10 * points.Size() -1) % points.Size() + 1;99n2 = n1+1;100if (n2 > points.Size()) n2 = 1;101n3 = n2+1;102if (n3 > points.Size()) n3 = 1;103n4 = n3+1;104if (n4 > points.Size()) n4 = 1;105106// (*mycout) << "t = " << t << " n = " << n << " loct = " << loct107// << " n1 = " << n1 << endl;108109110hp(0) = b1 * points.Get(n1)(0) + b2 * points.Get(n2)(0) +111b3 * points.Get(n3)(0) + b4 * points.Get(n4)(0);112hp(1) = b1 * points.Get(n1)(1) + b2 * points.Get(n2)(1) +113b3 * points.Get(n3)(1) + b4 * points.Get(n4)(1);114return hp;115}116117Vec<2> BSplineCurve2d :: EvalPrime (double t) const118{119int n, n1, n2, n3, n4;120double loct, db1, db2, db3, db4;121Vec<2> hv;122123n = int(t);124loct = t - n;125126db1 = 0.5 * (loct - 1);127db4 = 0.5 * loct;128db2 = -db4;129db3 = -db1;130131n1 = (n + 10 * points.Size() -1) % points.Size() + 1;132n2 = n1+1;133if (n2 > points.Size()) n2 = 1;134n3 = n2+1;135if (n3 > points.Size()) n3 = 1;136n4 = n3+1;137if (n4 > points.Size()) n4 = 1;138139hv(0) = db1 * points.Get(n1)(0) + db2 * points.Get(n2)(0) +140db3 * points.Get(n3)(0) + db4 * points.Get(n4)(0);141hv(1) = db1 * points.Get(n1)(1) + db2 * points.Get(n2)(1) +142db3 * points.Get(n3)(1) + db4 * points.Get(n4)(1);143return hv;144}145146Vec<2> BSplineCurve2d :: EvalPrimePrime (double t) const147{148int n, n1, n2, n3, n4;149double ddb1, ddb2, ddb3, ddb4;150Vec<2> hv;151152n = int(t);153// double loct = t - n;154155ddb1 = 0.5;156ddb4 = 0.5;157ddb2 = -0.5;158ddb3 = -0.5;159160n1 = (n + 10 * points.Size() -1) % points.Size() + 1;161n2 = n1+1;162if (n2 > points.Size()) n2 = 1;163n3 = n2+1;164if (n3 > points.Size()) n3 = 1;165n4 = n3+1;166if (n4 > points.Size()) n4 = 1;167168hv(0) = ddb1 * points.Get(n1)(0) + ddb2 * points.Get(n2)(0) +169ddb3 * points.Get(n3)(0) + ddb4 * points.Get(n4)(0);170hv(1) = ddb1 * points.Get(n1)(1) + ddb2 * points.Get(n2)(1) +171ddb3 * points.Get(n3)(1) + ddb4 * points.Get(n4)(1);172return hv;173}174175176int BSplineCurve2d :: SectionUsed (double t) const177{178int n1 = int(t);179n1 = (n1 + 10 * points.Size() - 1) % points.Size() + 1;180return (intervallused.Get(n1) == 0);181}182183void BSplineCurve2d :: Reduce (const Point<2> & p, double rad)184{185int n1, n;186int j;187double minx, miny, maxx, maxy;188189// (*testout) << "Reduce: " << p << "," << rad << endl;190191redlevel++;192193for (n1 = 1; n1 <= points.Size(); n1++)194{195if (intervallused.Get(n1) != 0) continue;196197minx = maxx = points.Get(n1)(0);198miny = maxy = points.Get(n1)(1);199200n = n1;201for (j = 1; j <= 3; j++)202{203n++;204if (n > points.Size()) n = 1;205if (points.Get(n)(0) < minx) minx = points.Get(n)(0);206if (points.Get(n)(1) < miny) miny = points.Get(n)(1);207if (points.Get(n)(0) > maxx) maxx = points.Get(n)(0);208if (points.Get(n)(1) > maxy) maxy = points.Get(n)(1);209}210211if (minx > p(0) + rad || maxx < p(0) - rad ||212miny > p(1) + rad || maxy < p(1) - rad)213{214intervallused.Elem(n1) = redlevel;215// (*testout) << 0;216}217else218{219// (*testout) << 1;220intervallused.Elem(n1) = 0;221}222}223// (*testout) << endl;224}225226void BSplineCurve2d :: UnReduce ()227{228int i;229for (i = 1; i <= intervallused.Size(); i++)230if (intervallused.Get(i) == redlevel)231intervallused.Set (i, 0);232redlevel--;233}234235void BSplineCurve2d :: Print (ostream & ost) const236{237ost << "SplineCurve: " << points.Size() << " points." << endl;238for (int i = 1; i <= points.Size(); i++)239ost << "P" << i << " = " << points.Get(i) << endl;240}241}242243244