12 #include <wfmath/intersect.h> 18 using WFMath::CoordType;
23 typedef WFMath::Point<2> Point2;
24 typedef WFMath::Vector<2> Vector2;
27 static bool isZero(CoordType d)
29 return (std::fabs(d) < WFMath::numeric_constants<CoordType>::epsilon());
55 Point2
clip(
const Point2& u,
const Point2& v)
const 57 CoordType dy = v.y() - u.y();
58 CoordType dx = v.x() - u.x();
65 CoordType t = (
topZ - u.y()) / dy;
66 return Point2(u.x() + t * dx,
topZ);
86 return p.y() < bottomZ;
94 Point2
clip(
const Point2& u,
const Point2& v)
const 96 CoordType dy = v.y() - u.y();
97 CoordType dx = v.x() - u.x();
100 CoordType t = (u.y() - bottomZ) / -dy;
101 return Point2(u.x() + t * dx, bottomZ);
121 return p.x() >= leftX;
129 Point2
clip(
const Point2& u,
const Point2& v)
const 131 CoordType dy = v.y() - u.y();
132 CoordType dx = v.x() - u.x();
137 CoordType t = (leftX - u.x()) / dx;
138 return Point2(leftX, u.y() + t * dy);
158 return p.x() < rightX;
166 Point2
clip(
const Point2& u,
const Point2& v)
const 168 CoordType dy = v.y() - u.y();
169 CoordType dx = v.x() - u.x();
174 CoordType t = (u.x() - rightX) / -dx;
175 return Point2(rightX, u.y() + t * dy);
182 template <
class Clip>
183 WFMath::Polygon<2> sutherlandHodgmanKernel(
const WFMath::Polygon<2>& inpoly,
const Clip& clipper)
185 WFMath::Polygon<2> outpoly;
187 if (!inpoly.isValid())
return inpoly;
188 std::size_t points = inpoly.numCorners();
189 if (points < 3)
return outpoly;
191 Point2 lastPt = inpoly.getCorner(points - 1);
192 bool lastInside = clipper.inside(lastPt);
194 for (std::size_t p = 0; p < points; ++p) {
196 Point2 curPt = inpoly.getCorner(p);
197 bool inside = clipper.inside(curPt);
202 outpoly.addCorner(outpoly.numCorners(), curPt);
205 outpoly.addCorner(outpoly.numCorners(), clipper.clip(lastPt, curPt));
210 outpoly.addCorner(outpoly.numCorners(), clipper.clip(lastPt, curPt));
211 outpoly.addCorner(outpoly.numCorners(), curPt);
234 m_box = p.boundingBox();
239 if (!WFMath::Contains(
m_box, Point2(x,z),
false))
return false;
241 return WFMath::Contains(m_shape, Point2(x,z),
false);
249 WFMath::AxisBox<2> segBox(s.
getRect());
250 WFMath::Polygon<2> clipped = sutherlandHodgmanKernel(m_shape,
TopClip(segBox.lowCorner().y()));
252 clipped = sutherlandHodgmanKernel(clipped,
BottomClip(segBox.highCorner().y()));
253 clipped = sutherlandHodgmanKernel(clipped,
LeftClip(segBox.lowCorner().x()));
254 clipped = sutherlandHodgmanKernel(clipped,
RightClip(segBox.highCorner().x()));
261 return m_shape.numCorners() && (WFMath::Intersect(m_shape, s.
getRect(),
false) ||
262 WFMath::Contains(s.
getRect(), m_shape.getCorner(0),
false));
bool inside(const Point2 &p) const
Check a point is outside this clip.
bool inside(const Point2 &p) const
Check a point is outside this clip.
WFMath::Polygon< 2 > clipToSegment(const Segment &s) const
Clip the shape of this area to a given segment.
Helper to clip points to a given range.
bool inside(const Point2 &p) const
Check a point is outside this clip.
WFMath::AxisBox< 2 > getRect() const
The 2d area covered by this segment.
Point2 clip(const Point2 &u, const Point2 &v) const
Determine the point where a line crosses this clip.
Area(int layer, bool hole)
Constructor.
bool inside(const Point2 &p) const
Check a point is outside this clip.
Point2 clip(const Point2 &u, const Point2 &v) const
Determine the point where a line crosses this clip.
Point2 clip(const Point2 &u, const Point2 &v) const
Determine the point where a line crosses this clip.
CoordType leftX
Left of x range.
CoordType bottomZ
Bottom of z range.
bool checkIntersects(const Segment &s) const override
Class storing heightfield and other data for a single fixed size square area of terrain defined by fo...
CoordType rightX
Right of x range.
Helper to clip points to a given range.
WFMath::AxisBox< 2 > m_box
The bounding box of the geometric shape.
CoordType topZ
Top of z range.
Point2 clip(const Point2 &u, const Point2 &v) const
Determine the point where a line crosses this clip.
Helper to clip points to a given range.
Helper to clip points to a given range.
bool contains(WFMath::CoordType x, WFMath::CoordType z) const
Determine if a point is contained by the shape of this area.
void setShape(const WFMath::Polygon< 2 > &p)
Set the geometric shape of this area.