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);
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);
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));