Пример #1
0
double OGRCompoundCurve::get_Area() const
{
    if( IsEmpty() || !get_IsClosed() )
        return 0;

    // Optimization for convex rings.
    if( IsConvex() )
    {
        // Compute area of shape without the circular segments.
        OGRPointIterator* poIter = getPointIterator();
        OGRLineString oLS;
        oLS.setNumPoints( getNumPoints() );
        OGRPoint p;
        for( int i = 0; poIter->getNextPoint(&p); i++ )
        {
            oLS.setPoint( i, p.getX(), p.getY() );
        }
        double dfArea = oLS.get_Area();
        delete poIter;

        // Add the area of the spherical segments.
        dfArea += get_AreaOfCurveSegments();

        return dfArea;
    }

    OGRLineString* poLS = CurveToLine();
    double dfArea = poLS->get_Area();
    delete poLS;

    return dfArea;
}
Пример #2
0
bool Polygon::DiagonalExists(int i, int j) const
{
	assume(p.size() >= 3);
	assume(i >= 0);
	assume(j >= 0);
	assume(i < (int)p.size());
	assume(j < (int)p.size());
#ifndef MATH_ENABLE_INSECURE_OPTIMIZATIONS
	if (p.size() < 3 || i < 0 || j < 0 || i >= (int)p.size() || j >= (int)p.size())
		return false;
#endif
	assume(IsPlanar());
	assume(i != j);
	if (i == j) // Degenerate if i == j.
		return false;
	if (i > j)
		Swap(i, j);
	assume(i+1 != j);
	if (i+1 == j) // Is this LineSegment an edge of this polygon?
		return false;

	Plane polygonPlane = PlaneCCW();
	LineSegment diagonal = polygonPlane.Project(LineSegment(p[i], p[j]));

	// First check that this diagonal line is not intersected by an edge of this polygon.
	for(int k = 0; k < (int)p.size(); ++k)
		if (!(k == i || k+1 == i || k == j))
			if (polygonPlane.Project(LineSegment(p[k], p[k+1])).Intersects(diagonal))
				return false;

	return IsConvex();
}
Пример #3
0
double OGRCircularString::get_Area() const
{
    if( IsEmpty() || !get_IsClosed() )
        return 0;

    double cx = 0.0;
    double cy = 0.0;
    double square_R = 0.0;

    if( IsFullCircle(cx, cy, square_R) )
    {
        return M_PI * square_R;
    }

    // Optimization for convex rings.
    if( IsConvex() )
    {
        // Compute area of shape without the circular segments.
        double dfArea = get_LinearArea();

        // Add the area of the spherical segments.
        dfArea += get_AreaOfCurveSegments();

        return dfArea;
    }

    OGRLineString* poLS = CurveToLine();
    const double dfArea = poLS->get_Area();
    delete poLS;

    return dfArea;
}
Пример #4
0
bool Polyhedron::ContainsConvex(const float3 &point) const
{
	assume(IsConvex());
	for(int i = 0; i < NumFaces(); ++i)
		if (FacePlane(i).SignedDistance(point) > 0.f)
			return false;

	return true;
}
Пример #5
0
Polygon::Polygon(std::vector<sf::Vector2f> points, sf::Color color, sf::Vector2f position)
{
	//No points = nothing to do
	if (points.size() < 0)
		return;

	//Check if shape is concave or convex
	if (IsConvex(points))
	{
		//If it is convex, we only have 1 shape in m_shapes
		CreateConvexPolygon(points, color);
	}

	m_shape.setPosition(position);
}
Пример #6
0
bool Polyhedron::ClipLineSegmentToConvexPolyhedron(const float3 &ptA, const float3 &dir,
                                                   float &tFirst, float &tLast) const
{
	assume(IsConvex());

	// Intersect line segment against each plane.
	for(int i = 0; i < NumFaces(); ++i)
	{
		/* Denoting the dot product of vectors a and b with <a,b>, we have:

		   The points P on the plane p satisfy the equation <P, p.normal> == p.d.
		   The points P on the line have the parametric equation P = ptA + dir * t.
		   Solving for the distance along the line for intersection gives
		
		   t = (p.d - <p.normal, ptA>) / <p.normal, dir>.
		*/

		Plane p = FacePlane(i);
		float denom = Dot(p.normal, dir);
		float dist = p.d - Dot(p.normal, ptA);

		// Avoid division by zero. In this case the line segment runs parallel to the plane.
		if (Abs(denom) < 1e-5f)
		{
			// If <P, p.normal> < p.d, then the point lies in the negative halfspace of the plane, which is inside the polyhedron.
			// If <P, p.normal> > p.d, then the point lies in the positive halfspace of the plane, which is outside the polyhedron.
			// Therefore, if p.d - <ptA, p.normal> == dist < 0, then the whole line is outside the polyhedron.
			if (dist < 0.f)
				return false;
		}
		else
		{
			float t = dist / denom;
			if (denom < 0.f) // When entering halfspace, update tFirst if t is larger.
				tFirst = Max(t, tFirst);
			else // When exiting halfspace, updeate tLast if t is smaller.
				tLast = Min(t, tLast);

			if (tFirst > tLast)
				return false; // We clipped the whole line segment.
		}
	}
	return true;
}
Пример #7
0
float3 Polyhedron::ClosestPointConvex(const float3 &point) const
{
	assume(IsConvex());
	if (ContainsConvex(point))
		return point;
	float3 closestPoint = float3::nan;
	float closestDistance = FLT_MAX;
	for(int i = 0; i < NumFaces(); ++i)
	{
		float3 closestOnPoly = FacePolygon(i).ClosestPoint(point);
		float d = closestOnPoly.DistanceSq(point);
		if (d < closestDistance)
		{
			closestPoint = closestOnPoly;
			closestDistance = d;
		}
	}
	return closestPoint;
}
void VoronoiPolygonSite::DrawSiteFilled()
{
	
  // DETERMINE WINDING ORDER (ONLY DRAW CAP ON CCW, "OUTSIDE" IS REALLY OUTSIDE)
  if (OrderingIsCCW(Pts,NumPts))
  {
    // DETERMINE IF POLYGON IS CONVEX OR NONCONVEX
    if (IsConvex(Pts,NumPts))
    {
      glBegin(GL_POLYGON);
        for (int k=0; k<(NumPts*2); k+=2)
          glVertex2fv(&(Pts[k]));
      glEnd();
    }
    else  // NONCONVEX POLYGONS MUST BE TRIANGULATED (OPENGL DOES NOT HANDLE NONCONVEX)
    {
      //DrawNonconvexPoly(Pts,NumPts);
      DrawSiteFilledWithTessPoly(Pts, NumPts);
    }
  } else {
     DrawSiteFilledWithTessPoly(Pts, NumPts);
  }

}
Пример #9
0
TriangulateEC<Real>::TriangulateEC (int iQuantity,
    const Vector2<Real>* akPosition, Query::Type eQueryType, Real fEpsilon,
    int*& raiIndex)
{
    assert(iQuantity >= 3 && akPosition);
    if (eQueryType == Query::QT_FILTERED)
    {
        assert((Real)0.0 <= fEpsilon && fEpsilon <= (Real)1.0);
    }

    Vector2<Real>* akSPosition = 0;
    Vector2<Real> kMin, kMax, kRange;
    Real fScale;
    int i;

    switch (eQueryType)
    {
    case Query::QT_INT64:
        // Transform the vertices to the square [0,2^{20}]^2.
        Vector2<Real>::ComputeExtremes(iQuantity,akPosition,kMin,kMax);
        kRange = kMax - kMin;
        fScale = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
        fScale *= (Real)(1 << 20);
        akSPosition = WM4_NEW Vector2<Real>[iQuantity];
        for (i = 0; i < iQuantity; i++)
        {
            akSPosition[i] = (akPosition[i] - kMin)*fScale;
        }
        m_pkQuery = WM4_NEW Query2Int64<Real>(iQuantity,akSPosition);
        break;
    case Query::QT_INTEGER:
        // Transform the vertices to the square [0,2^{24}]^2.
        Vector2<Real>::ComputeExtremes(iQuantity,akPosition,kMin,kMax);
        kRange = kMax - kMin;
        fScale = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
        fScale *= (Real)(1 << 24);
        akSPosition = WM4_NEW Vector2<Real>[iQuantity];
        for (i = 0; i < iQuantity; i++)
        {
            akSPosition[i] = (akPosition[i] - kMin)*fScale;
        }
        m_pkQuery = WM4_NEW Query2TInteger<Real>(iQuantity,akSPosition);
        break;
    case Query::QT_REAL:
        // Transform the vertices to the square [0,1]^2.
        Vector2<Real>::ComputeExtremes(iQuantity,akPosition,kMin,kMax);
        kRange = kMax - kMin;
        fScale = (kRange[0] >= kRange[1] ? kRange[0] : kRange[1]);
        akSPosition = WM4_NEW Vector2<Real>[iQuantity];
        for (i = 0; i < iQuantity; i++)
        {
            akSPosition[i] = (akPosition[i] - kMin)*fScale;
        }
        m_pkQuery = WM4_NEW Query2<Real>(iQuantity,akSPosition);
        break;
    case Query::QT_RATIONAL:
        // No transformation of the input data.
        m_pkQuery = WM4_NEW Query2TRational<Real>(iQuantity,akPosition);
        break;
    case Query::QT_FILTERED:
        // No transformation of the input data.
        m_pkQuery = WM4_NEW Query2Filtered<Real>(iQuantity,akPosition,
            fEpsilon);
        break;
    }

    int iQm1 = iQuantity - 1;
    raiIndex = WM4_NEW int[3*iQm1];
    int* piIndex = raiIndex;

    m_akVertex = WM4_NEW Vertex[iQuantity];
    m_iCFirst = -1;
    m_iCLast = -1;
    m_iRFirst = -1;
    m_iRLast = -1;
    m_iEFirst = -1;
    m_iELast = -1;

    // Create a circular list of the polygon vertices for dynamic removal of
    // vertices.  Keep track of two linear sublists, one for the convex
    // vertices and one for the reflex vertices.  This is an O(N) process
    // where N is the number of polygon vertices.
    for (i = 0; i <= iQm1; i++)
    {
        // link the vertices
        Vertex& rkV = V(i);
        rkV.VPrev = (i > 0 ? i-1 : iQm1);
        rkV.VNext = (i < iQm1 ? i+1 : 0);

        // link the convex/reflex vertices
        if (IsConvex(i))
        {
            InsertAfterC(i);
        }
        else
        {
            InsertAfterR(i);
        }
    }

    if (m_iRFirst == -1)
    {
        // polygon is convex, just triangle fan it
        for (i = 1; i < iQm1; i++)
        {
            *piIndex++ = 0;
            *piIndex++ = i;
            *piIndex++ = i+1;
        }
        return;
    }

    // Identify the ears and build a circular list of them.  Let V0, V1, and
    // V2 be consecutive vertices forming a triangle T.  The vertex V1 is an
    // ear if no other vertices of the polygon lie inside T.  Although it is
    // enough to show that V1 is not an ear by finding at least one other
    // vertex inside T, it is sufficient to search only the reflex vertices.
    // This is an O(C*R) process where C is the number of convex vertices and
    // R is the number of reflex vertices, N = C+R.  The order is O(N^2), for
    // example when C = R = N/2.
    for (i = m_iCFirst; i != -1; i = V(i).SNext)
    {
        if (IsEar(i))
        {
            InsertEndE(i);
        }
    }
    V(m_iEFirst).EPrev = m_iELast;
    V(m_iELast).ENext = m_iEFirst;

    // Remove the ears, one at a time.
    while (true)
    {
        // add triangle of ear to output
        int iVPrev = V(m_iEFirst).VPrev;
        int iVNext = V(m_iEFirst).VNext;
        *piIndex++ = iVPrev;
        *piIndex++ = m_iEFirst;
        *piIndex++ = iVNext;

        // remove the vertex corresponding to the ear
        RemoveV(m_iEFirst);
        if (--iQuantity == 3)
        {
            // Only one triangle remains, just remove the ear and copy it.
            RemoveE();
            iVPrev = V(m_iEFirst).VPrev;
            iVNext = V(m_iEFirst).VNext;
            *piIndex++ = iVPrev;
            *piIndex++ = m_iEFirst;
            *piIndex++ = iVNext;
            break;
        }

        // removal of the ear can cause an adjacent vertex to become an ear
        bool bWasReflex;

        Vertex& rkVPrev = V(iVPrev);
        if (!rkVPrev.IsEar)
        {
            bWasReflex = !rkVPrev.IsConvex;
            if (IsConvex(iVPrev))
            {
                if (bWasReflex)
                {
                    RemoveR(iVPrev);
                }

                if (IsEar(iVPrev))
                {
                    InsertBeforeE(iVPrev);
                }
            }
        }

        Vertex& rkVNext = V(iVNext);
        if (!rkVNext.IsEar)
        {
            bWasReflex = !rkVNext.IsConvex;
            if (IsConvex(iVNext))
            {
                if (bWasReflex)
                {
                    RemoveR(iVNext);
                }

                if (IsEar(iVNext))
                {
                    InsertAfterE(iVNext);
                }
            }
        }

        // remove the ear
        RemoveE();
    }

    WM4_DELETE[] akSPosition;
    WM4_DELETE m_pkQuery;
}