// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu) // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License v2 or later. #include "region2d.h" /************************************************************************/ void side2d::Init(const pt2d& pt0, const pt2d& pt1, coord scale) { pt= pt0 * scale; // to get normal, take vector from pt0 to pt1 and rotate -90 deg normal= (pt1 -pt0).Right90(); length= normal.Dist(); unitNormal= normal; unitNormal.Normalize(1); } /************************************************************************/ // The number of srcPts should be equal to the number of points (and the // number of sides) in the region2d. In other words, region2d's are self- // closing; the last src pt need not be, and should not be, the same as the // first src pt in order to close the region2d region2d::region2d(coord *srcPts, coord scale) { Init(srcPts,scale); } /*-------------------------------------------------------------------------*/ void region2d::Init(coord *srcPts, coord scale) { numSides= 0; if (srcPts) { pt2d firstPt(srcPts); pt2d pt= firstPt; while (*srcPts != COORD_MAX) { pt2d prevPt= pt; pt= pt2d(srcPts); sides[numSides++].Init(prevPt,pt,scale); } sides[numSides++].Init(pt,firstPt,scale); } } /*-------------------------------------------------------------------------*/ void region2d::Init(pt2d *srcPts, coord scale) { numSides= 0; if (srcPts) { pt2d firstPt(srcPts); pt2d pt= firstPt; while (srcPts->x != COORD_MAX) { pt2d prevPt= pt; pt= pt2d(srcPts); sides[numSides++].Init(prevPt,pt,scale); } sides[numSides++].Init(pt,firstPt,scale); } } /*-------------------------------------------------------------------------*/ void region2d::operator+=(const pt2d& offset) { forii(numSides) sides[i].pt += offset; } void region2d::operator*=(coord scale) { forii(numSides) sides[i].pt *= scale; } void region2d::TransformTo(const pt2d& offset, ang2d ang, const pt2d& sc, pt2d destPts[]) { forii(numSides) { pt2d p= sides[i].pt; p *= sc; destPts[i]= (p >> ang) + offset; } } // In: pt = point which this region2d may contain // Out: dist <=0 = neg. dist to nearest side; region does contain pt // >0 = dist to a side which faces pt; region does not contain pt // s = side void region2d::CheckIfContains(const pt2d& pt, coord& dist, side2d*& s) { coord nearestInsideDist; side2d *nearestInsideSide; s= &sides[0]; dist= ((pt - s->pt).Dot(s->normal)) / s->length; if (dist >0) return; nearestInsideDist= dist; nearestInsideSide= s; for(int i=1; i pt).Dot(s->normal)) / s->length; if (dist >0) return; if (dist >nearestInsideDist) nearestInsideDist= dist; } dist= nearestInsideDist; s= nearestInsideSide; }