virtual bool load(MgStorage* s) { pt1.set(s->readFloat("x1", pt1.x), s->readFloat("y1", pt1.y)); pt2.set(s->readFloat("x2", pt2.x), s->readFloat("y2", pt2.y)); return true; }
double YMin() const { return min3 (p1->Y(), p2->Y(), p3->Y()); }
inline Vec2d operator- (const Point2d & p1, const Point2d & p2) { return Vec2d (p1.X() - p2.X(), p1.Y() - p2.Y()); }
inline Point2d Center () const { return Point2d( (p1.X()+p2.X()+p3.X())/3, (p1.Y()+p2.Y()+p3.Y())/3); }
double YMax() const { return max3 (p1->Y(), p2->Y(), p3->Y()); }
double XMax() const { return max3 (p1.X(), p2.X(), p3.X()); }
double XMin() const { return min3 (p1.X(), p2.X(), p3.X()); }
/// Bounding box used to calculate quad tree nodes. In local coordinate system. virtual Mbr getTotalExtents() { Mbr mbr(Point2f(ll.x(),ll.y()),Point2f(ur.x(),ur.y())); return mbr; }
float MgDot::_hitTest(const Point2d& pt, float, MgHitResult& res) const { res.nearpt = _point; return pt.distanceTo(_point); }
int netrule :: IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const { int i; int left, right, allleft, allright; double nx, ny, nl, c; if (p1.X() > fzmaxx && p2.X() > fzmaxx || p1.X() < fzminx && p2.X() < fzminx || p1.Y() > fzmaxy && p2.Y() > fzmaxy || p1.Y() < fzminy && p2.Y() < fzminy) return 0; for (i = 1; i <= transfreezone.Size(); i++) { if (freesetinequ.Get(i, 1) * p1.X() + freesetinequ.Get(i, 2) * p1.Y() + freesetinequ.Get(i, 3) > -1e-6 && freesetinequ.Get(i, 1) * p2.X() + freesetinequ.Get(i, 2) * p2.Y() + freesetinequ.Get(i, 3) > -1e-6 ) return 0; } nx = (p2.Y() - p1.Y()); ny = -(p2.X() - p1.X()); nl = sqrt (nx * nx + ny * ny); if (nl > 1e-8) { nx /= nl; ny /= nl; c = - (p1.X() * nx + p1.Y() * ny); allleft = 1; allright = 1; for (i = 1; i <= transfreezone.Size(); i++) { left = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c < 1e-7; right = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c > -1e-7; if (!left) allleft = 0; if (!right) allright = 0; } if (allleft || allright) return 0; } return 1; }
// 得到坐标系的原点origin,坐标轴矢量e0和e1 void Matrix2d::getCoordSystem(Vector2d& e0, Vector2d& e1, Point2d& origin) const { e0.set(m11, m12); e1.set(m21, m22); origin.set(dx, dy); }
bool MgArc::setCenterStartEnd(const Point2d& center, const Point2d& start) { float startAngle = (start - center).angle2(); return setCenterRadius(center, start.distanceTo(center), startAngle, 0); }
//----------------------------------------------------------------------------- // Find all points where a line through a and b intersects our surface, and // add them to the list. If seg is true then report only intersections that // lie within the finite line segment (not including the endpoints); otherwise // we work along the infinite line. And we report either just intersections // inside the trim curve, or any intersection with u, v in [0, 1]. And we // either disregard or report tangent points. //----------------------------------------------------------------------------- void SSurface::AllPointsIntersecting(Vector a, Vector b, List<SInter> *l, bool seg, bool trimmed, bool inclTangent) { if(LineEntirelyOutsideBbox(a, b, seg)) return; Vector ba = b.Minus(a); double bam = ba.Magnitude(); List<Inter> inters; ZERO(&inters); // All the intersections between the line and the surface; either special // cases that we can quickly solve in closed form, or general numerical. Vector center, axis, start, finish; double radius; if(degm == 1 && degn == 1) { // Against a plane, easy. Vector n = NormalAt(0, 0).WithMagnitude(1); double d = n.Dot(PointAt(0, 0)); // Trim to line segment now if requested, don't generate points that // would just get discarded later. if(!seg || (n.Dot(a) > d + LENGTH_EPS && n.Dot(b) < d - LENGTH_EPS) || (n.Dot(b) > d + LENGTH_EPS && n.Dot(a) < d - LENGTH_EPS)) { Vector p = Vector::AtIntersectionOfPlaneAndLine(n, d, a, b, NULL); Inter inter; ClosestPointTo(p, &(inter.p.x), &(inter.p.y)); inters.Add(&inter); } } else if(IsCylinder(&axis, ¢er, &radius, &start, &finish)) { // This one can be solved in closed form too. Vector ab = b.Minus(a); if(axis.Cross(ab).Magnitude() < LENGTH_EPS) { // edge is parallel to axis of cylinder, no intersection points return; } // A coordinate system centered at the center of the circle, with // the edge under test horizontal Vector u, v, n = axis.WithMagnitude(1); u = (ab.Minus(n.ScaledBy(ab.Dot(n)))).WithMagnitude(1); v = n.Cross(u); Point2d ap = (a.Minus(center)).DotInToCsys(u, v, n).ProjectXy(), bp = (b.Minus(center)).DotInToCsys(u, v, n).ProjectXy(), sp = (start. Minus(center)).DotInToCsys(u, v, n).ProjectXy(), fp = (finish.Minus(center)).DotInToCsys(u, v, n).ProjectXy(); double thetas = atan2(sp.y, sp.x), thetaf = atan2(fp.y, fp.x); Point2d ip[2]; int ip_n = 0; if(fabs(fabs(ap.y) - radius) < LENGTH_EPS) { // tangent if(inclTangent) { ip[0] = Point2d::From(0, ap.y); ip_n = 1; } } else if(fabs(ap.y) < radius) { // two intersections double xint = sqrt(radius*radius - ap.y*ap.y); ip[0] = Point2d::From(-xint, ap.y); ip[1] = Point2d::From( xint, ap.y); ip_n = 2; } int i; for(i = 0; i < ip_n; i++) { double t = (ip[i].Minus(ap)).DivPivoting(bp.Minus(ap)); // This is a point on the circle; but is it on the arc? Point2d pp = ap.Plus((bp.Minus(ap)).ScaledBy(t)); double theta = atan2(pp.y, pp.x); double dp = WRAP_SYMMETRIC(theta - thetas, 2*PI), df = WRAP_SYMMETRIC(thetaf - thetas, 2*PI); double tol = LENGTH_EPS/radius; if((df > 0 && ((dp < -tol) || (dp > df + tol))) || (df < 0 && ((dp > tol) || (dp < df - tol)))) { continue; } Vector p = a.Plus((b.Minus(a)).ScaledBy(t)); Inter inter; ClosestPointTo(p, &(inter.p.x), &(inter.p.y)); inters.Add(&inter); } } else { // General numerical solution by subdivision, fallback int cnt = 0, level = 0; AllPointsIntersectingUntrimmed(a, b, &cnt, &level, &inters, seg, this); } // Remove duplicate intersection points inters.ClearTags(); int i, j; for(i = 0; i < inters.n; i++) { for(j = i + 1; j < inters.n; j++) { if(inters.elem[i].p.Equals(inters.elem[j].p)) { inters.elem[j].tag = 1; } } } inters.RemoveTagged(); for(i = 0; i < inters.n; i++) { Point2d puv = inters.elem[i].p; // Make sure the point lies within the finite line segment Vector pxyz = PointAt(puv.x, puv.y); double t = (pxyz.Minus(a)).DivPivoting(ba); if(seg && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) { continue; } // And that it lies inside our trim region Point2d dummy = { 0, 0 }; int c = bsp->ClassifyPoint(puv, dummy, this); if(trimmed && c == SBspUv::OUTSIDE) { continue; } // It does, so generate the intersection SInter si; si.p = pxyz; si.surfNormal = NormalAt(puv.x, puv.y); si.pinter = puv; si.srf = this; si.onEdge = (c != SBspUv::INSIDE); l->Add(&si); } inters.Clear(); }
virtual bool load(MgStorage* s) { pt.set(s->readFloat("x", pt.x), s->readFloat("y", pt.y)); vec.set(s->readFloat("w", vec.x), s->readFloat("h", vec.y)); return true; }
Vec2d Delta () const { return Vec2d (p2->X()-p1->X(), p2->Y()-p1->Y()); }
int netrule :: IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const { if ( (p1.X() > fzmaxx && p2.X() > fzmaxx) || (p1.X() < fzminx && p2.X() < fzminx) || (p1.Y() > fzmaxy && p2.Y() > fzmaxy) || (p1.Y() < fzminy && p2.Y() < fzminy) ) return 0; for (int i = 1; i <= transfreezone.Size(); i++) { if (freesetinequ.Get(i, 1) * p1.X() + freesetinequ.Get(i, 2) * p1.Y() + freesetinequ.Get(i, 3) > -1e-8 && // -1e-6 freesetinequ.Get(i, 1) * p2.X() + freesetinequ.Get(i, 2) * p2.Y() + freesetinequ.Get(i, 3) > -1e-8 // -1e-6 ) return 0; } double nx = (p2.Y() - p1.Y()); double ny = -(p2.X() - p1.X()); double nl = sqrt (nx * nx + ny * ny); if (nl > 1e-8) { nx /= nl; ny /= nl; double c = - (p1.X() * nx + p1.Y() * ny); bool allleft = true; bool allright = true; for (int i = 1; i <= transfreezone.Size(); i++) { bool left = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() * ny + c < 1e-7; bool right = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() * ny + c > -1e-7; if (!left) allleft = false; if (!right) allright = false; } if (allleft || allright) return false; } return true; }
double Length2 () const { return sqr (p1->X() - p2->X()) + sqr (p1->Y() - p2->Y()); }
Segment::Segment(const Point2d &aa,const Point2d &bb) { init(); a.set(aa.getX(),aa.getY(),0); b.set(bb.getX(),bb.getY(),0); }
double YMax() const { return max3 (p1.Y(), p2.Y(), p3.Y()); }
void Segment::setAB(const Point2d &aa,const Point2d &bb) { a.set(aa.getX(),aa.getY(),0); b.set(bb.getX(),bb.getY(),0); }
double YMin() const { return min3 (p1.Y(), p2.Y(), p3.Y()); }
double Segment::distance2(const Point2d &p) { return distance2(Point3d(p.getX(),p.getY(),0)); }
double XMax() const { return max3 (p1->X(), p2->X(), p3->X()); }
virtual bool processLine(int, int&, const Point2d& startpt, const Point2d& endpt) { length += startpt.distanceTo(endpt); return true; }
double XMin() const { return min3 (p1->X(), p2->X(), p3->X()); }
Vec2d Delta () const { return Vec2d (p2.X()-p1.X(), p2.Y()-p1.Y()); }
Point2d Center () const { return Point2d( (p1->X()+p2->X()+p3->X())/3, (p1->Y()+p2->Y()+p3->Y())/3); }
double Length2 () const { return sqr (p1.X() - p2.X()) + sqr (p1.Y() - p2.Y()); }
inline Point2d operator- (const Point2d & p1, const Vec2d & v) { return Point2d (p1.X() - v.X(), p1.Y() - v.Y()); }
void netrule :: LoadRule (istream & ist) { char buf[256]; char ch; Point2d p; INDEX_2 lin; int i, j; DenseMatrix tempoldutonewu(20, 20), tempoldutofreearea(20, 20), tempoldutofreearealimit(20, 20); tempoldutonewu = 0; tempoldutofreearea = 0; tempoldutofreearealimit = 0; noldp = 0; noldl = 0; ist.get (buf, sizeof(buf), '"'); ist.get (ch); ist.get (buf, sizeof(buf), '"'); ist.get (ch); // if(name != NULL) delete [] name; name = new char[strlen (buf) + 1]; strcpy (name, buf); //(*testout) << "name " << name << endl; // (*mycout) << "Rule " << name << " found." << endl; do { ist >> buf; //(*testout) << "buf " << buf << endl; if (strcmp (buf, "quality") == 0) { ist >> quality; } else if (strcmp (buf, "mappoints") == 0) { ist >> ch; while (ch == '(') { ist >> p.X(); ist >> ch; // ',' ist >> p.Y(); ist >> ch; // ')' points.Append (p); noldp++; tolerances.SetSize (noldp); tolerances.Elem(noldp).f1 = 1.0; tolerances.Elem(noldp).f2 = 0; tolerances.Elem(noldp).f3 = 1.0; ist >> ch; while (ch != ';') { if (ch == '{') { ist >> tolerances.Elem(noldp).f1; ist >> ch; // ',' ist >> tolerances.Elem(noldp).f2; ist >> ch; // ',' ist >> tolerances.Elem(noldp).f3; ist >> ch; // '}' } else if (ch == 'd') { // delpoints.Append (noldp); ist >> ch; // 'e' ist >> ch; // 'l' }