Polygone aneinanderkleben

takidoso

Erfahrenes Mitglied
Hallo und Halli,
Ich habe folgende Problematik und bin mir über einen guten Ansatz nicht so arg sicher.
Man stelle sich verscheidene Polygone vor, die bei einander liegen und sich auch eigetnlich aneinander schmiegen.
nun würde ich gerne dass ich als Anwender die Möglichkeit habe dass 2 gewählte Polygone tatsächlich aneinander geklebt werden.

Routinen wie "gib nächsten Punkt einer Linie" und "ist ein Punkt innerhalb eienr bestimmten Richweite zu einem gegebenen Polygon" stehen dafür glücklicherweise zur Verfügung.

Mein erster Einfall ist dass man herausfinden muss welche Punkte des (leicht) zu verändernden Polygons welchen Linien des Ziel Polygons am nächsten stehen. Nur irgendwie bin ich mir nicht über das weitere im Klaren.
nehmen wir mal an ich finde dann solchen nahen Punkt-Linien-Distanzen die auf Grund ungenauen Zeichnens nicht identisch sein müssen wie wird dem Algorithmus klar gemacht, dass es genau diese Punkte sind?

Muss ich da mit Statistischen Mitteln Arbeiten um dann eine gewisse Unschärfe zu gewinnen, diei miri aber genau diese gesuchten Punkte identifiziert?

wie sähe so etwas aus, oder gibt es da bessere Ideen?

mit Ratschlägen erhoffenden Grüßen

Takidoso
 
Juchhuuuu
ich habe nun selbst einen netten Einfall gehabt, der sogar ziemlich gut auf Anhieb funktioniert hat...

verbal umschrieben mache ich folgendes, wobei Goalpolygon sei das Vieleck, an welches ich ein Mutablepolygon ankleben will und Zielpunkte die Randpunkte des Goalpolygons sind, die den Eckpunkten des Mutablepolygons am nächsten sind:

sammele Zielpunkte des Goalpolygons und ihre Entfernungen,
die den Punkten des Mutablepolygon am nächsten sind
in eine Map und ermittele die kleinste Distanz


bilde Differenz zwsichen kleinster Entfernung und den Restlichen
und verändere die mutable Points bei denen die Entfernungsdifferenz 100 nicht übersteigt
(es handelt sich hierbei um quadrierete Entfernungen)


Die Routine gluePolygons sieht dann so aus
Code:
/**
     * die am nächsten stehenden Linien bzw Punkte von Polygon 1 und 2 werden
     * zusammengeführt wobei Polygon 1 angepasst wird (seine Punkte verändert werden) 
     * @param poly1
     * @param poly2
     */
    private void gluePolygons(Polygon2D mutedPoly, Polygon2D goalPoly)
    {
    	
    	Map nearestPointsAndDistances = new HashMap();
    	
    	
    	// sammele Zielpunkte des Zielpolygons und ihre Entfernungen,  
    	// die den Punkten des zu ändernden Polygons am nächsten sind
    	// in eine Map und ermittele die kleinste Distanz
    	Point2D[] mutablePolyPoints = mutedPoly.getRawPoints();
    	double closest = Double.POSITIVE_INFINITY; 
    	
    	for (int i=0; i<mutablePolyPoints.length; i++)
    	{    		
    		Object[] pointAndDistance = getNearestPointAndDistanceOffAllLines(mutablePolyPoints[i], goalPoly);    		
    		nearestPointsAndDistances.put(mutablePolyPoints[i].toString(),pointAndDistance);
    		closest = Math.min(closest,((Double)pointAndDistance[1]).doubleValue());
    	}
    	
    	// bilde Differenz zwsichen kleinster Entfernung und den Restlichen
    	// und verändere die mutable Points bei denen die Entfernungsdifferenz 100 nicht übersteigt
    	// (es handelt sich hierbei um quadrierete Entfernungen)
    	for (int i=0; i<mutablePolyPoints.length; i++)
    	{
    		Object[] nPoiAndDis = (Object[])nearestPointsAndDistances.get(mutablePolyPoints[i].toString());
    		
    		double diff = ((Double)nPoiAndDis[1]).doubleValue() - closest;
    		if (diff <= 100)
    		{
    			mutablePolyPoints[i].copyFrom((Point2D)nPoiAndDis[0]);
    		}    		
    	}    	    	
    }

die nächste Routine holt die einem gegebenen Punkt am nächsten liegenden Randpunkte eines gegebenen Polygons und ihre jeweilige Entfernungen.
Code:
/**
     * gibt nächstgelegenen Punkt des Polygons in Bezug auf gegebenen Punkt und seine
     * quadrierte Entfernung zurück 
     * @param analysedPoint
     * @param goalPoly
     * @return Object[2] wobei 
     * Objec[0]  = (Point2D)aller nächster Punkt des gegebenen Zielpolygons und zu analysierender Punkt 
     * Object[1] = (Double) quadrierte Entfernung zwischen zu analysierendne und ermittelten Punkt
     * 
     */
    private Object[] getNearestPointAndDistanceOffAllLines(Point2D analysedPoint, Polygon2D goalPoly)
    {
    	Point2D[][] lines = getPolygonLines(goalPoly);
    	
    	Point2D nearestPointofAll = null;
    	double minDistanceSqr = Double.POSITIVE_INFINITY; 
    	
    	
    	for (int i=0; i< lines.length; i++)
    	{
    		
    		Point2D nearestPoint = Polygon2D.getNearestPointOnLine(lines[i][0], lines[i][1],analysedPoint);
    		double distanceSqr = nearestPoint.getSquaredDistanceTo(analysedPoint);
    		
    		if ( distanceSqr < minDistanceSqr)
    		{
    			nearestPointofAll = nearestPoint;
    			minDistanceSqr    = distanceSqr; 
    		}    		    		    		    		
    	}
    	    	
    	return new Object[] {nearestPointofAll, new Double(minDistanceSqr)};
    }

Diese Routine sammelt aus den Eckpunkten eines Polygons die Linien
Code:
private Point2D[][] getPolygonLines(Polygon2D poly)
    {
    	Point2D []   points = poly.getRawPoints();
    	Point2D [][] lines  = new Point2D[points.length][2];
    	for (int i=0; i<points.length-1; i++)
    	{
    		lines[i][0] = new Point2D(points[i]);
    		lines[i][1] = new Point2D(points[i+1]);
    	}
    	lines[points.length-1][0] = new Point2D(points[points.length-1]);
    	lines[points.length-1][1] = new Point2D(points[0]);
    	return lines;
    }

Da ich wirklich keine so dolle mathematischen Fähigkeiten habe, habe ich hierfür mich einer Polygon- und Punkteklasse bedient, die ich nach etwas googeln ausfindig machte.
Sie ist von Finnegan Southey und liegt auf seiner Homepage

Also wer solche geometrische Sache mal braucht mag sich bedienen :)

in diesem Sinne

Takidoso
 

Neue Beiträge

Zurück