bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy ) const
{
    BOX2I bbox = BBox();
    bbox.Inflate( aAccuracy );

    if( !m_closed || PointCount() < 3 || !BBox().Contains( aPt ) )
        return false;

    bool inside = false;

    /**
     * To check for interior points, we draw a line in the positive x direction from
     * the point.  If it intersects an even number of segments, the point is outside the
     * line chain (it had to first enter and then exit).  Otherwise, it is inside the chain.
     *
     * Note: slope might be denormal here in the case of a horizontal line but we require our
     * y to move from above to below the point (or vice versa)
     */
    for( int i = 0; i < PointCount(); i++ )
    {
        const auto p1 = CPoint( i );
        const auto p2 = CPoint( i + 1 ); // CPoint wraps, so ignore counts
        const auto diff = p2 - p1;

        if( diff.y != 0 )
        {
            const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y );

            if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) )
                inside = !inside;
        }
    }
    return inside && !PointOnEdge( aPt, aAccuracy );
}
Beispiel #2
0
int PointInPolygon(int n, Point p[]) {
	int i, area = 0;
	for (i = 0; i < n; ++i) {
		//area += p[(i+1) % n].y * (p[i].x - p[(i+2) % n].x); // 如果将式子展开,可以简化成这个样子,减小运算量
		area += p[i].x * p[(i+1)%n].y - p[i].y * p[(i+1) % n].x;
	}
	return (abs(area) - PointOnEdge(n, p)) / 2 + 1;
}
Beispiel #3
0
float3 Polygon::RandomPointOnEdge(LCG &rng) const
{
	return PointOnEdge(rng.Float());
}
Beispiel #4
0
vec AABB::RandomPointOnEdge(LCG &rng) const
{
	int i = rng.Int(0, 11);
	float f = rng.Float();
	return PointOnEdge(i, f);
}
Beispiel #5
0
float3 OBB::RandomPointOnEdge(LCG &rng) const
{
    return PointOnEdge(rng.Int(0, 11), rng.Float());
}