⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intersection.java

📁 OpenJGraph是一个开源的Java库
💻 JAVA
字号:
package salvo.jesus.geom;

import java.awt.*;
import java.awt.geom.*;
import org.apache.log4j.Category;

/**
 * The Intersection class provides methods for determining
 * the intersection point of two lines and the intersection
 * point of a line and a GeneralPath object.
 *
 * @author		Jesus M. Salvo Jr.
 */
public class Intersection {

    /**
     * Log4J Category. The name of the category is the fully qualified name of the
     * enclosing class.
     */
    static        Category    logger;

    static {
        logger = Category.getInstance( Intersection.class.getName());
    }

  /**
   * Returns the intersection point of two lines.
   *
   * @param   line1   First line
   * @param   line2   Second line
   * @return  The Point object where the two lines intersect. This method
   * returns null if the two lines do not intersect.
   * @throws  <tt>MultipleIntersectionException</tt> when the two lines
   * have more than one intersection point.
   */
  static public Point getIntersection( Line2D line1, Line2D line2 )
    throws MultipleIntersectionException
  {
    double dyline1, dxline1;
    double dyline2, dxline2, e, f;
    double x1line1, y1line1, x2line1, y2line1;
    double x1line2, y1line2, x2line2, y2line2;

    if ( !line1.intersectsLine( line2 ) )
      return null;

    /* first, check to see if the segments intersect by parameterization
       on s and t; if s and t are both between [0,1], then the
       segments intersect */
    x1line1 = (double)line1.getX1();
    y1line1 = (double)line1.getY1();
    x2line1 = (double)line1.getX2();
    y2line1 = (double)line1.getY2();

    x1line2 = (double)line2.getX1();
    y1line2 = (double)line2.getY1();
    x2line2 = (double)line2.getX2();
    y2line2 = (double)line2.getY2();

    /* check to see if the segments have any endpoints in common. If they do,
       then return the endpoints as the intersection point */
    if ((x1line1==x1line2) && (y1line1==y1line2))
    {
      return (new Point( (int) x1line1, (int) y1line1));
    }
    if ((x1line1==x2line2) && (y1line1==y2line2))
    {
      return (new Point( (int) x1line1, (int) y1line1));
    }
    if ((x2line1==x1line2) && (y2line1==y1line2))
    {
      return (new Point( (int) x2line1, (int) y2line1));
    }
    if ((x2line1==x2line2) && (y2line1==y2line2))
    {
      return (new Point( (int) x2line1, (int) y2line1));
    }

    dyline1 = -( y2line1 - y1line1 );
    dxline1 = x2line1 - x1line1;

    dyline2 = -( y2line2 - y1line2 );
    dxline2 = x2line2 - x1line2;

    e = -(dyline1 * x1line1) - (dxline1 * y1line1);
    f = -(dyline2 * x1line2) - (dxline2 * y1line2);

    /* compute the intersection point using
      ax+by+e = 0 and cx+dy+f = 0

      If there is more than 1 intersection point between two lines,
    */
    if( (dyline1 * dxline2 - dyline2 * dxline1) == 0 )
        throw new MultipleIntersectionException();
    return (new Point(
      (int) (-(e * dxline2 - dxline1 * f)/(dyline1 * dxline2 - dyline2 * dxline1)),
      (int) (-(dyline1 * f - dyline2 * e)/(dyline1 * dxline2 - dyline2 * dxline1))));
  }

  /**
   * Returns the intersection point of a line and a GeneralPath. Given that
   * a line can intersect more than one segment of a GeneralPath, this method
   * will return the intersection point of the first segment, returned by
   * a PathIterator, and the line. No consideration is taken if the line
   * intersects more than one segment of the GeneralPath since this is internally
   * used by salvo.jesus.graph.VisualEdge wherein the edge of a line
   * will intersect only one segment of the VisualVertex's GeneralPath.
   *
   * @param   line1   First line
   * @param   path    GeneralPath representing line segments
   * @return  The Point object where the line and the GeneralPath object intersect.
   * This method returns null if they do not intersect.
   */
  static public Point getIntersection( Line2D line, GeneralPath path ){
    Line2D.Double	rectline = new Line2D.Double();
    Point	        intersectpoint = null;
    Point	        testintersectpoint = null;
    Point           previousintersectpoint;
    Point           lineorigin = new Point( (int) line.getX1(), (int) line.getY1() );
    FlatteningPathIterator    pathiterator;
    double          coords[] = new double[6];
    int             segmenttype;
    double          prevx = -1, prevy = -1;

    // Iterate through the segments
    pathiterator = new FlatteningPathIterator( path.getPathIterator( null ), 1.0 );
    while( !pathiterator.isDone() ){
      segmenttype = pathiterator.currentSegment( coords );
      // Since we are are iterating through a GeneralPath, all segments
      // are guaranteed to be a line.
      switch (segmenttype){
        case PathIterator.SEG_MOVETO:
          prevx = coords[0]; prevy = coords[1];
          break;
        case PathIterator.SEG_QUADTO:
        case PathIterator.SEG_CUBICTO:
        case PathIterator.SEG_LINETO:
          // If prevx or prev = -1, then we do not have an initial SEG_MOVETO yet.
          // Therefore, the if block does not get executed and the coordinates
          // are treated as if it were a SEG_MOVETO.
          if( prevx != -1 && prevy != 1 ){
            // Check if the line segment intersects with the line in the argument
            rectline.setLine( prevx, prevy, coords[0], coords[1] );

            // Workaround at the moment
            try {
                testintersectpoint = getIntersection( line, rectline );
            }
            catch( MultipleIntersectionException ex ) {
                logger.error( "Multiple Intersections Detected", ex );
                testintersectpoint = null;
            }

            if( testintersectpoint != null ) {
              previousintersectpoint = intersectpoint;
              intersectpoint = testintersectpoint;
              // Yes, the line segment intersects with the line, but does it have
              // a shorter distance to the line in the argument, so assign the
              // variable intersectpoint to this intersection point.

              // However, if the new intersection point is farther away from
              // the origin of the line than that of the previous intersection point,
              // revert the intersect point back to the previous intereection point.
              if( previousintersectpoint != null &&
                  (lineorigin.distance( intersectpoint ) > lineorigin.distance( previousintersectpoint )) ) {
                intersectpoint = previousintersectpoint;
              }
            }
          }
          prevx = coords[0]; prevy = coords[1];
          break;
      }
      pathiterator.next();
    }
    return intersectpoint;
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -