Exemple #1
0
bool LineIntersection(const CIPoint& A1, const CIPoint& A2, const CIPoint& B1, const CIPoint& B2, CXPoint* X, double *ta, double *tb)
{
  double x21 = A2.x - A1.x;
  double y21 = A2.y - A1.y;
  double x31 = B1.x - A1.x;
  double y13 = A1.y - B1.y;
  double x43 = B2.x - B1.x;
  double y43 = B2.y - B1.y;
  double del = x21 * y43 - x43 * y21;
  if (FEqual(del, 0))
  {
    X->x = NaN;		
    X->y = NaN;		
    return false;
  }
  *ta = (x43 * y13 + x31 * y43) / del;
  *tb = (x21 * y13 + x31 * y21) / del;
  
  X->x = A1.x + *ta * x21;
  X->y = A1.y + *ta * y21;
  return (*ta>=0 && *ta<=1 && *tb>=0 && *tb<=1);
}
Exemple #2
0
bool LineIntersection(const CXPoint& A1, const CXPoint& A2, const CXPoint& B1, const CXPoint& B2, CXPoint* X)
{
  double x21 = A2.x - A1.x;
  double y21 = A2.y - A1.y;
  double x31 = B1.x - A1.x;
  double y13 = A1.y - B1.y;
  double x43 = B2.x - B1.x;
  double y43 = B2.y - B1.y;
  double del = x21 * y43 - x43 * y21;
  if (FEqual(del, 0))
  {
    X->x = NaN;		
    X->y = NaN;		
    return false;
  }
  double a = (x43 * y13 + x31 * y43) / del;
  double b = (x21 * y13 + x31 * y21) / del;
  
  X->x = A1.x + a * x21;
  X->y = A1.y + a * y21;
  return (a>=0 && a<=1 && b>=0 && b<=1);
}
Exemple #3
0
double CXVector::LinearDependent(const CXVector& rs) const 
{
  if ((FEqual(rs.x,0) && !FEqual(x,0))) return 0;
  if ((FEqual(rs.y,0) && !FEqual(y,0))) return 0;
  return FEqual(x / rs.x, y / rs.y) ? x / rs.x : 0;
}
EarClipper::VertexList::iterator EarClipper::RayCastFromMaxInteriorPointToOuterPolygon(const FVector2& maxInteriorPoint, FVector2& intersectionPointOnEdge, VertexList::iterator& pointOnEdgeWithMaximumXIter)
{
   //a) Call the vertex on the hole with the maximum x coordinate P. Call the ray { P, (1,0) } R. Intersect R
   //   with the edges of the outer polygon. Find the edge whose intersection is closest to P. Call this edge E.
   //   If R goes through E entirely, then the mutually visible vertex is the endpoint on E closest to P. Otherwise,
   //   if R goes through one of the endpoints of E, then the mutually visible vertex is this endpoint. Otherwise,
   //   R intersects the line segment at a point other than the endpoints (see b)

   VertexList::iterator verticesEnd = vertices.end();

   VertexList::iterator mutuallyVisibleVertexIter = verticesEnd;

   VertexList::iterator possibleMutuallyVisibleVertex = verticesEnd;

   Line2D_t rayFromMaxVertex(maxInteriorPoint, Vec2D::XAxis(), true);

   float minDistance = std::numeric_limits<float>::max();

   LineSegment2D_t lineSegmentOnOuterPolygon;
   FVector2 intersectionPoint1, intersectionPoint2;
   VertexList::iterator pointOnThisEdgeWithMaximumXIter = verticesEnd;

   for (VertexList::iterator vertexIterator = vertices.begin(); vertexIterator != verticesEnd; ++vertexIterator)
   {
      VertexList::iterator nextVertexIterator = vertexIterator.next();

      lineSegmentOnOuterPolygon.P1 = *(vertexIterator->point);
      lineSegmentOnOuterPolygon.P2 = *(nextVertexIterator->point);

      IntersectionType intersection = rayFromMaxVertex.LineSegmentIntersection(lineSegmentOnOuterPolygon, intersectionPoint1, intersectionPoint2, EXPERIMENTAL_TOLERANCE);

      if ((intersection == IntersectionType::LineSegment) || (intersection == IntersectionType::Point))
      {
         possibleMutuallyVisibleVertex = vertexIterator;
         bool rayHitEndPointOfEdge = true;

         if (lineSegmentOnOuterPolygon.P1.x > lineSegmentOnOuterPolygon.P2.x)
         {
            pointOnThisEdgeWithMaximumXIter = vertexIterator;
         }
         else
         {
            pointOnThisEdgeWithMaximumXIter = nextVertexIterator;
         }

         if (intersection == IntersectionType::LineSegment)
         {
            if (lineSegmentOnOuterPolygon.P1.x < lineSegmentOnOuterPolygon.P2.x)
            {
               possibleMutuallyVisibleVertex = vertexIterator;
            }
            else
            {
               possibleMutuallyVisibleVertex = nextVertexIterator;
            }
         }
         else if (intersection == IntersectionType::Point)
         {
            if (intersectionPoint1 == lineSegmentOnOuterPolygon.P1)
            {
               possibleMutuallyVisibleVertex = vertexIterator;
            }
            else if (intersectionPoint1 == lineSegmentOnOuterPolygon.P2)
            {
               possibleMutuallyVisibleVertex = nextVertexIterator;
            }
            else
            {
               rayHitEndPointOfEdge = false;
            }
         }

         float distance = rayHitEndPointOfEdge ? (possibleMutuallyVisibleVertex->point->x - maxInteriorPoint.x) : (intersectionPoint1.x - maxInteriorPoint.x);

         bool sameishDistance = FEqual(distance, minDistance);

         if ((distance < minDistance) || sameishDistance)
         {
            bool takeThisVertex = true;

            if (sameishDistance)
            {
               const FVector2* beforeMutuallyVisibleVertex = possibleMutuallyVisibleVertex.previous()->point;

               takeThisVertex = (GetConvexOrReflexVertexType(beforeMutuallyVisibleVertex, possibleMutuallyVisibleVertex->point, &maxInteriorPoint) == VertexType::Convex);
            }

            if (takeThisVertex)
            {
               if (rayHitEndPointOfEdge)
               {
                  mutuallyVisibleVertexIter = possibleMutuallyVisibleVertex;
               }
               else
               {
                  mutuallyVisibleVertexIter = verticesEnd;
                  pointOnEdgeWithMaximumXIter = pointOnThisEdgeWithMaximumXIter;
                  intersectionPointOnEdge = intersectionPoint1;
               }

               minDistance = distance;
            }
         }
      }
   }

   return mutuallyVisibleVertexIter;
}