2011-03-03 19 views
12

Polygon ve Line2D'un kesişim noktasını verecek herhangi bir işlev var mı?Java - Çokgen ve Çizgi'nin kesişme noktası

Bildiğim bir Çokgen ve bir satır segmentim var Kesişme noktasının gerçek değerini boole yanıtı olarak istemiyorum.

+1

Herhalde ben bir nokta dışında olduğunu biliyorum çünkü ben, tam olarak 1 yerde kesişir biliyoruz ve biridir eklemek gerekir çokgen içinde. Ama ben poligonun hangi segmentinin – bryan

cevap

8

java.awt.geom.Area.intersect(Area), Polygon'unuzla Area(Shape) yapıcısını kullanarak ve Line2D'u bir Alan olarak kesiştirmek için bir alan olarak kesiştirerek, kesişen Alanı size verecektir.

2

Birden çok yerde kesişebileceğini unutmayın.

ml = (ly1-ly2)/(lx1-lx2); 
mp = (ply-pl2)/(px1-px2); 

her bir hattın Y kesişimi Bul (eğim m) en Her çizgisinin eğimini bulmak poligon P çizgi parçası ve gerçek bir çizgi parçası

L

diyelim // y = mx + b buradaki b, y-kesişme noktasıdır bl = ly1 - (ml * lx1); bp = pi1 - (pl * px1);

Sen x değeri için çözebilir: Sonra Y İşte

y = ml * x + bl 

almak için denklem birine o X fiş

x = (bp - bl)/(ml - mp) 

algoritmasının bir uygulamaya versiyonu

class pointtest { 

    static float[] intersect(float lx1, float ly1, float lx2, float ly2, 
          float px1, float py1, float px2, float py2) { 
     // calc slope 
     float ml = (ly1-ly2)/(lx1-lx2); 
     float mp = (py1-py2)/(px1-px2);  

     // calc intercept   
     float bl = ly1 - (ml*lx1); 
     float bp = py1 - (mp*px1); 

     float x = (bp - bl)/(ml - mp); 
     float y = ml * x + bl; 

     return new float[]{x,y}; 
    } 

    public static void main(String[] args) { 

     float[] coords = intersect(1,1,5,5,1,4,5,3); 
     System.out.println(coords[0] + " " + coords[1]); 

    } 
} 

ve sonuçlar:

+2

kesiştiğini bilmiyorum, burada kapsanmayan bazı durumlar olduğuna dikkat etmeliyim. Çizgiler aynı olduğunda ne olur? Çizgiler kesişmediğinde ne olur (eşit eğim)? Kesişme çizginin dışında gerçekleşirse ne olur? Ya biri sıfır eğimli ise? Okuyucu için bir egzersiz olarak bırakılan bazı özel durumlar var. – corsiKa

9

İşte buradasınız. İlginç yöntemler getIntersections ve getIntersection'dır. Birincisi tüm çokgen parçalara ayrılır ve kesişimleri kontrol eder, ikincisi gerçek hesaplamayı yapar. Hesaplamanın ciddi şekilde optimize edilebileceğini ve bölüme göre 0'ın kontrol edilemeyeceğini unutmayın. Bu yalnızca çokgenler için de çalışacaktır. Kübik ve kuadratik eğriler için hesaplamalar yaparsanız, başka şekillerle çalışmaya adapte edilebilir. Line2D.Float yerine Line2D.Double kullanıldığı varsayılmaktadır. Bir küme, çoğaltılmış noktalardan kaçınmak için kullanılır (çokgen köşe kavşaklarında oluşabilir).

Lütfen bunu kapsamlı bir test olmaksızın kullanmayın, çünkü bunu sadece hızlı bir şekilde hackledim ve tamamen ses olduğundan emin değilim. Büyük bir başarıyla

package quickpolygontest; 

import java.awt.Polygon; 
import java.awt.geom.Line2D; 
import java.awt.geom.PathIterator; 
import java.awt.geom.Point2D; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.Set; 

public class Main { 

    public static void main(String[] args) throws Exception { 

     final Polygon poly = new Polygon(new int[]{1,2,2,1}, new int[]{1,1,2,2}, 4); 
     final Line2D.Double line = new Line2D.Double(2.5, 1.3, 1.3, 2.5); 
     final Set<Point2D> intersections = getIntersections(poly, line); 
     for(Iterator<Point2D> it = intersections.iterator(); it.hasNext();) { 
      final Point2D point = it.next(); 
      System.out.println("Intersection: " + point.toString()); 
     } 

    } 

    public static Set<Point2D> getIntersections(final Polygon poly, final Line2D.Double line) throws Exception { 

     final PathIterator polyIt = poly.getPathIterator(null); //Getting an iterator along the polygon path 
     final double[] coords = new double[6]; //Double array with length 6 needed by iterator 
     final double[] firstCoords = new double[2]; //First point (needed for closing polygon path) 
     final double[] lastCoords = new double[2]; //Previously visited point 
     final Set<Point2D> intersections = new HashSet<Point2D>(); //List to hold found intersections 
     polyIt.currentSegment(firstCoords); //Getting the first coordinate pair 
     lastCoords[0] = firstCoords[0]; //Priming the previous coordinate pair 
     lastCoords[1] = firstCoords[1]; 
     polyIt.next(); 
     while(!polyIt.isDone()) { 
      final int type = polyIt.currentSegment(coords); 
      switch(type) { 
       case PathIterator.SEG_LINETO : { 
        final Line2D.Double currentLine = new Line2D.Double(lastCoords[0], lastCoords[1], coords[0], coords[1]); 
        if(currentLine.intersectsLine(line)) 
         intersections.add(getIntersection(currentLine, line)); 
        lastCoords[0] = coords[0]; 
        lastCoords[1] = coords[1]; 
        break; 
       } 
       case PathIterator.SEG_CLOSE : { 
        final Line2D.Double currentLine = new Line2D.Double(coords[0], coords[1], firstCoords[0], firstCoords[1]); 
        if(currentLine.intersectsLine(line)) 
         intersections.add(getIntersection(currentLine, line)); 
        break; 
       } 
       default : { 
        throw new Exception("Unsupported PathIterator segment type."); 
       } 
      } 
      polyIt.next(); 
     } 
     return intersections; 

    } 

    public static Point2D getIntersection(final Line2D.Double line1, final Line2D.Double line2) { 

     final double x1,y1, x2,y2, x3,y3, x4,y4; 
     x1 = line1.x1; y1 = line1.y1; x2 = line1.x2; y2 = line1.y2; 
     x3 = line2.x1; y3 = line2.y1; x4 = line2.x2; y4 = line2.y2; 
     final double x = (
       (x2 - x1)*(x3*y4 - x4*y3) - (x4 - x3)*(x1*y2 - x2*y1) 
       )/
       (
       (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4) 
       ); 
     final double y = (
       (y3 - y4)*(x1*y2 - x2*y1) - (y1 - y2)*(x3*y4 - x4*y3) 
       )/
       (
       (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4) 
       ); 

     return new Point2D.Double(x, y); 

    } 

} 
+0

Güzel !!!!!!!!!!! – Evgeny

2

, ben bu yaklaşımı kullandı:

Sana JTS kullanmayı öneriyoruz Poligon ve Line2D Nesneleri kullanmak kısıtlı değilseniz
Area a = new Area(shape1); 
Area b = new Area(shape2); 
b.intersect(a); 
if (!b.isEmpty()) { 
    //Shapes have non-empty intersection, so do you actions. 
    //In case of need, actual intersection is in Area b. (its destructive operation) 
} 
0

.

Basit kod örneği:

// create ring: P1(0,0) - P2(0,10) - P3(10,10) - P4(0,10) 
LinearRing lr = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0,0), new Coordinate(0,10), new Coordinate(10,10), new Coordinate(10,0), new Coordinate(0,0)}); 
// create line: P5(5, -1) - P6(5, 11) -> crossing the ring vertically in the middle 
LineString ls = new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(5,-1), new Coordinate(5,11)}); 
// calculate intersection points 
Geometry intersectionPoints = lr.intersection(ls); 
// simple output of points 
for(Coordinate c : intersectionPoints.getCoordinates()){ 
    System.out.println(c.toString()); 
} 

Sonucu geçerli:

(5.0, 0.0, NaN) 
(5.0, 10.0, NaN) 
İlgili konular