Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geom2d.cpp
3206 views
#include <mystdlib.h>12#include <myadt.hpp>3#include <gprim.hpp>45#ifndef M_PI6#define M_PI 3.141592653589793238467#endif89namespace netgen10{1112ostream & operator<<(ostream & s, const Point2d & p)13{14return s << "(" << p.px << ", " << p.py << ")";15}1617ostream & operator<<(ostream & s, const Vec2d & v)18{19return s << "(" << v.vx << ", " << v.vy << ")";20}2122#ifdef none23ostream & operator<<(ostream & s, const Line2d & l)24{25return s << l.p1 << "-" << l.p2;26}2728ostream & operator<<(ostream & s, const TRIANGLE2D & t)29{30return s << t.p1 << "-" << t.p2 << "-" << t.p3;31}32#endif333435double Fastatan2 (double x, double y)36{37if (y > 0)38{39if (x > 0)40return y / (x+y);41else42return 1 - x / (y-x);43}44else if (y < 0)45{46if (x < 0)47return 2 + y / (x+y);48else49return 3 - x / (y-x);50}51else52{53if (x >= 0)54return 0;55else56return 2;57}58}596061double Angle (const Vec2d & v)62{63if (v.X() == 0 && v.Y() == 0)64return 0;6566double ang = atan2 (v.Y(), v.X());67if (ang < 0) ang+= 2 * M_PI;68return ang;69}7071double FastAngle (const Vec2d & v)72{73return Fastatan2 (v.X(), v.Y());74}7576double Angle (const Vec2d & v1, const Vec2d & v2)77{78double ang = Angle(v2) - Angle(v1);79if (ang < 0) ang += 2 * M_PI;80return ang;81}8283double FastAngle (const Vec2d & v1, const Vec2d & v2)84{85double ang = FastAngle(v2) - FastAngle(v1);86if (ang < 0) ang += 4;87return ang;88}8990/*91int CW (const Point2d & p1,const Point2d & p2,const Point2d & p3)92{93return Cross (p2 - p1, p3 - p2) < 0;94}9596int CCW (const Point2d & p1,const Point2d & p2,const Point2d & p3)97{98return Cross (p2 - p1, p3 - p2) > 0;99}100*/101102double Dist2(const Line2d & g, const Line2d & h )103{104double dd = 0.0, d1,d2,d3,d4;105Point2d cp = CrossPoint(g,h);106107if ( Parallel(g,h) || !IsOnLine(g,cp) || !IsOnLine(h,cp) )108{109d1 = Dist2(g.P1(),h.P1());110d2 = Dist2(g.P1(),h.P2());111d3 = Dist2(g.P2(),h.P1());112d4 = Dist2(g.P2(),h.P2());113if (d1<d2) d2 = d1;114if (d3<d4) d4 = d3;115dd = ( d2 < d4 ) ? d2 : d4;116}117return dd;118}119120121Point2d CrossPoint (const Line2d & l1, const Line2d & l2)122{123double den = Cross (l1.Delta(), l2.Delta());124double num = Cross ( (l2.P1() - l1.P1()), l2.Delta());125126if (den == 0)127return l1.P1();128else129return l1.P1() + (num/den) * l1.Delta();130}131132133int CrossPointBarycentric (const Line2d & l1, const Line2d & l2,134double & lam1, double & lam2)135{136// p = l1.1 + lam1 (l1.2-l1.1) = l2.1 + lam2 (l2.2-l2.1)137double a11 = l1.p2.X() - l1.p1.X();138double a21 = l1.p2.Y() - l1.p1.Y();139double a12 = -(l2.p2.X() - l2.p1.X());140double a22 = -(l2.p2.Y() - l2.p1.Y());141142double b1 = l2.p1.X() - l1.p1.X();143double b2 = l2.p1.Y() - l1.p1.Y();144145double det = a11*a22 - a12 * a21;146if (det == 0)147return 1;148149lam1 = (a22 * b1 - a12 * b2) / det;150lam2 = (a11 * b2 - a21 * b1) / det;151return 0;152}153154155156157int Parallel (const Line2d & l1, const Line2d & l2, double peps)158{159double p = fabs (Cross (l1.Delta(), l2.Delta()));160// (*mycout) << endl << p << " " << l1.Length() << " " << l2.Length() << endl;161return p <= peps * l1.Length() * l2.Length();162}163164int IsOnLine (const Line2d & l, const Point2d & p, double heps)165{166double c1 = (p - l.P1()) * l.Delta();167double c2 = (p - l.P2()) * l.Delta();168double d = fabs (Cross ( (p - l.P1()), l.Delta()));169double len2 = l.Length2();170171return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2;172}173174#ifdef none175int IsOnLine (const PLine2d & l, const Point2d & p, double heps)176{177double c1 = (p - l.P1()) * l.Delta();178double c2 = (p - l.P2()) * l.Delta();179double d = fabs (Cross ( (p - l.P1()), l.Delta()));180double len2 = l.Length2();181182return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2;183}184185int IsOnLongLine (const Line2d & l, const Point2d & p)186{187double d = fabs (Cross ( (p - l.P1()), l.Delta()));188return d <= EPSGEOM * l.Length();189}190191int Hit (const Line2d & l1, const Line2d & l2, double heps)192{193double den = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l2.P2()));194double num1 = Cross ( (l2.P1() - l1.P1()), (l2.P1() - l2.P2()));195double num2 = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l1.P1()));196num1 *= sgn (den);197num2 *= sgn (den);198den = fabs (den);199200int ch = (-den * heps <= num1 && num1 <= den * (1 + heps) &&201-den * heps <= num2 && num2 <= den * (1 + heps));202return ch;203}204205206void Line2d :: GetNormal (Line2d & n) const207{208double ax = P2().X()-P1().X(),209ay = P2().Y()-P1().Y();210Point2d mid(P1().X()+.5*ax, P1().Y()+.5*ay);211212n=Line2d(mid,Point2d(mid.X()+ay,mid.Y()-ax)) ;213}214215Vec2d Line2d :: NormalDelta () const216{217Line2d tmp;218GetNormal(tmp);219return tmp.Delta();220}221222int TRIANGLE2D :: IsOn (const Point2d & p) const223{224return IsOnLine (Line2d (p1, p2), p) ||225IsOnLine (Line2d (p1, p3), p) ||226IsOnLine (Line2d (p2, p3), p);227}228229230int TRIANGLE2D :: IsIn (const Point2d & p) const231{232return ::CW(p, p1, p2) == ::CW(p, p2, p3) &&233::CW(p, p1, p2) == ::CW(p, p3, p1);234}235236237238int PTRIANGLE2D :: IsOn (const Point2d & p) const239{240return IsOnLine (Line2d (*p1, *p2), p) ||241IsOnLine (Line2d (*p1, *p3), p) ||242IsOnLine (Line2d (*p2, *p3), p);243}244245246int PTRIANGLE2D :: IsIn (const Point2d & p) const247{248return ::CW(p, *p1, *p2) == ::CW(p, *p2, *p3) &&249::CW(p, *p1, *p2) == ::CW(p, *p3, *p1);250}251252#endif253254255256257258259Polygon2d :: Polygon2d ()260{261;262}263264Polygon2d :: ~Polygon2d ()265{266;267}268269void Polygon2d :: AddPoint (const Point2d & p)270{271points.Append(p);272}273274275double Polygon2d :: HArea () const276{277int i;278double ar = 0;279for (i = 1; i <= points.Size(); i++)280{281const Point2d & p1 = points.Get(i);282const Point2d & p2 = points.Get(i%points.Size()+1);283ar +=284(p2.X()-p1.X()) * p1.Y() -285(p2.Y()-p1.Y()) * p1.X();286}287return ar/2;288/*289CURSOR c;290double ar = 0;291Point2d * p1, * p2, p0 = Point2d(0, 0);292Vec2d v1, v2 = Vec2d(1, 0);293294p2 = points[points.Last()];295for (c = points.First(); c != points.Head(); c++)296{297p1 = p2;298p2 = points[c];299ar += Cross ( (*p2-*p1), (*p1 - p0));300}301return ar / 2;302*/303}304305306int Polygon2d :: IsOn (const Point2d & p) const307{308int i;309for (i = 1; i <= points.Size(); i++)310{311const Point2d & p1 = points.Get(i);312const Point2d & p2 = points.Get(i%points.Size()+1);313if (IsOnLine (Line2d(p1, p2), p)) return 1;314}315return 0;316/*317CURSOR c;318Point2d * p1, * p2;319320p2 = points[points.Last()];321for (c = points.First(); c != points.Head(); c++)322{323p1 = p2;324p2 = points[c];325if (IsOnLine (Line2d(*p1, *p2), p)) return 1;326}327return 0;328*/329}330331332int Polygon2d :: IsIn (const Point2d & p) const333{334int i;335double sum = 0, ang;336for (i = 1; i <= points.Size(); i++)337{338const Point2d & p1 = points.Get(i);339const Point2d & p2 = points.Get(i%points.Size()+1);340ang = Angle ( (p1 - p), (p2 - p) );341if (ang > M_PI) ang -= 2 * M_PI;342sum += ang;343}344return fabs(sum) > M_PI;345/*346CURSOR c;347Point2d * p1, * p2;348double sum = 0, ang;349350p2 = points[points.Last()];351for (c = points.First(); c != points.Head(); c++)352{353p1 = p2;354p2 = points[c];355ang = Angle ( (*p1 - p), (*p2 - p) );356if (ang > M_PI) ang -= 2 * M_PI;357sum += ang;358}359360return fabs(sum) > M_PI;361*/362}363364int Polygon2d :: IsConvex () const365{366/*367Point2d *p, *pold, *pnew;368char cw;369CURSOR c;370371if (points.Length() < 3) return 0;372373c = points.Last();374p = points[c];375c--;376pold = points[c];377pnew = points[points.First()];378cw = ::CW (*pold, *p, *pnew);379380for (c = points.First(); c != points.Head(); c++)381{382pnew = points[c];383if (cw != ::CW (*pold, *p, *pnew))384return 0;385pold = p;386p = pnew;387}388*/389return 0;390}391392393int Polygon2d :: IsStarPoint (const Point2d & p) const394{395/*396Point2d *pnew, *pold;397char cw;398CURSOR c;399400if (points.Length() < 3) return 0;401402pold = points[points.Last()];403pnew = points[points.First()];404405cw = ::CW (p, *pold, *pnew);406407for (c = points.First(); c != points.Head(); c++)408{409pnew = points[c];410if (cw != ::CW (p, *pold, *pnew))411return 0;412pold = pnew;413}414return 1;415*/416return 0;417}418419420Point2d Polygon2d :: Center () const421{422/*423double ai, a = 0, x = 0, y = 0;424Point2d * p, *p2;425Point2d p0 = Point2d(0, 0);426CURSOR c;427428p2 = points[points.Last()];429430for (c = points.First(); c != points.Head(); c++)431{432p = points[c];433ai = Cross (*p2 - p0, *p - p0);434x += ai / 3 * (p2->X() + p->X());435y += ai / 3 * (p2->Y() + p->Y());436a+= ai;437p2 = p;438}439if (a != 0)440return Point2d (x / a, y / a);441else442return Point2d (0, 0);443*/444return Point2d (0, 0);445}446447448449Point2d Polygon2d :: EqualAreaPoint () const450{451/*452double a11 = 0, a12 = 0, a21= 0, a22 = 0;453double b1 = 0, b2 = 0, dx, dy;454double det;455Point2d * p, *p2;456CURSOR c;457458p = points[points.Last()];459460for (c = points.First(); c != points.Head(); c++)461{462p2 = p;463p = points[c];464465dx = p->X() - p2->X();466dy = p->Y() - p2->Y();467468a11 += sqr (dy);469a12 -= dx * dy;470a21 -= dx * dy;471a22 += sqr (dx);472b1 -= dy * (p->X() * p2->Y() - p2->X() * p->Y());473b2 -= dx * (p->Y() * p2->X() - p2->Y() * p->X());474}475476det = a11 * a22 - a21 * a12;477478if (det != 0)479return Point2d ( (b1 * a22 - b2 * a12) / det,480(a11 * b2 - a21 * b1) / det);481else482return Point2d (0, 0);483*/484return Point2d (0, 0);485}486487488}489490491