# 2D-Simulation in individuell gestalbarer Umgebung



## HarryG32 (16. Feb 2012)

Hallo,


ich habe für eine Uniarbeit ein Applet geschrieben, das in groben Zügen folgendes können soll:

1.Editor:

> Zeichnen eines Gartens (Grundfläche, Polygone)
> Einfügen von Objekten (Ladestation, Bäume,...)
> Speichern/Laden von Gärten (Applet-Servlet-Komm.)
(> Editieren von Gärten)

Unter: "www.sammel-leidenschaft.at" kann man eine 1. Version des Programms betrachten.

Leider gibt es noch keinen passenden Hilfetext. Durch Klicken auf "Speichern" kann man gezeichnete Objekte speichern. Wenn der Garten (bzw. die Gartengrundfläche) eingezeichnet und gespeichert ist, kann man weitere Objekte einfügen.

2.Simulator:

 > Simulation des Mähverhaltens eines Rasenroboters in dem vorher gezeichneten (bzw. geladenen und editierten) Garten
 > Kontrollfunktionen (Starten, Stoppen, Pause, Geschwindigkeit einstellen)


Mein Problem liegt nun bei der Simulation. Ich bekomme die leider nicht gscheiht hin. Immer wenn ich denke ich hab's, kommt wieder ein neues Problem hinzu. Die Ausnahmenbehandlung wird mittlerweile immer unübersichtlicher. 

Grundsätzlich sollte der Mäher bei Kollision mit einem Ausfallwinkel abprallen, der gleich dem Einfallswinkel ist.  

Ich beginne mit einem Startwinkel und der Mähvektor hat eine festgelegte Länge. Der 1. Startpunkt ergibt sich aus der Position der Ladestation, später ist der Schnittpunkt der Startpunkt.  Die Überprüfung auf Schneiden von 2 Linien (Intersection) ist kein Problem, die Berechnung des Schnittpunktes auch nicht. 

Ein Hauptproblem ist, dass ich im Vorhinein nicht weiss wie groß die Gartenfläche ist und wo meine Maximalwerte liegen. Ich könnte ja sonst sagen:  if(p.x >= xmax){ vorzeichen *= -*1; p.x = x.max + vorzeichen * step;}

Ich hoffe ich konnte das Problem einigermaßen beschreiben und ihr könnt mir helfen.


----------



## Marco13 (16. Feb 2012)

Wenn man den Schnittpunkt hat, kann man den Winkel zwischen der bisherigen Strecke und der geschnittenen Kante ausrechnen - und damit doch auch die ausfallende Strecke?!


----------



## HarryG32 (19. Feb 2012)

Naja, wenn die Kante nicht gerade ist, ist das garnicht so einfach zu berechnen. Ich bekomme ein Dreieck ohne rechten Winkel und muss mir zuerst die Seiten berechnen. Dazu muss ich auch die Steigung der geschnittenen Linie berechnen. Also eine Menge Berechnungen, Ausnahmen, Vorzeichenänderungen noch nicht berücksichtigt.

Hier habe ich das kurz skizziert (ganz grob):

Webseite in Arbeit ...


----------



## Marco13 (19. Feb 2012)

Häm? Wirkt mein Morgenkaffe noch nicht, oder...?! Der Pfeilrichtung nach läuft er einfach die Rote linie entlang - und was ist die grüne Linie, und wo kommt der Schnittpunkt her?! 

Ich gehe mal davon aus, dass die Grüne Linie der eigentliche Weg ist, und die Rote nur ... "Rauschen"  Also, dann ist der dort markierte "Einfallswirkel" gesucht. 

Angenommen man hat sowohl den Richtungsvektor der Roten (A) als auch den der Schwarzen (B) Linie gegeben. Dann kann man beide Vektoren normalisieren(!), und mit
double angleRad = Math.acos(Ax * Bx + Ay * By);
den winkel der beiden zueinander ausrechnen...


----------



## HarryG32 (20. Feb 2012)

@Marko: Sorry, die Bezeichnung der Linien hätte ich etwas ausführlicher machen können...aber du hast es richtig interpretiert.  "Rauschen" finde ich gut  Ich wollte das Ganze mit Winkelfunktionen lösen, mit Vektorrechnung hab ich noch nie was gemacht...aber das werde ich gleich ändern.

"Normalisieren" scheint das Zauberwort zu sein  Danke für deine Hilfe, echt supa!


----------



## HarryG32 (22. Mrz 2012)

Hallo, wie kann ich das Ganze mit Winkelfunktionen durchführen???

Das Programm ist unter: Startseite Applet verfügbar...einfach "einen Garten laden" und "Simulieren" drücken....

Gegeben sind: Startwinkel / Schrittweite / Startpunkt / und die Richtung als Polarkoordinate (nach unten = 270°)

Den Endpunkt berechne ich mit Kosinus- und Sinussatz.....

  double radian = direction - startwinkel  (z.B.: 270° - 30°)

  public Vector2D processKartesianKoordinates(double radian, double hypo){

		double a = Math.cos(Math.toRadians(radian))*hypothenuse;
		double b = Math.sin(Math.toRadians(radian))*hypothenuse;	
		return new Vector2D(a,b);		
  }


Wie kann ich den Einfallswinkel/Ausfallswinkel effizient berechnen und wie behandle ich die Änderung der Richtung (und damit der Vorzeichen)....??


----------



## Marco13 (22. Mrz 2012)

Geht es um die Frage, wie man den Winkel zwischen zwei Vektoren berechnet, oder um die Frage, ob der Ausfallwinkel 180-Einfallwinkel ist?


----------



## HarryG32 (22. Mrz 2012)

Hier die Klasse für die Berechnung des Mähweges....

> berechnet Endpunkt
> berechnet Schnittpunkt
> überprüft auf Intersection
> veranlasst DrawingBoard zum 
Updaten der Simulation

PROBLEME: Der Ausfallswinkel sollte gleich Einfallswinkel sein, wie mach ich das am Besten??
Mit Winkelfunktionen oder Vektoren (ich hab's hier schon gemischt...). 

Hier habe ich ein gutes Beispiel gefunden, so wär's optimal:

http://www.java-forum.org/mathematik/35920-vektor-gerade-spiegeln.html 


```
package simulation;

import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;
import java.util.Vector;

import database.ElementBasis;
import database.GardenElement;
import drawing.DrawingBoard;

public class PathProcessor {
	
	private ElementBasis basis;
	private DrawingBoard board;
	private Vector2D start, end, kartesian;
	
	private double beta = 30.0;
	private double hypo = 30.0;
	private double direction = 270;
	
	private Line2D.Double simuLine;
	private Line2D.Double modelLine;
	
	private double step = 70;
		
	//Gartenmodell übergeben
	public PathProcessor(ElementBasis baseRef, DrawingBoard boardRef){
		basis = baseRef;
		board = boardRef;
			
	}
	public void init(){
		start = new Vector2D(basis.getStationPoint().x+7, basis.getStationPoint().y+17);
		show("Startpunkt: (" +start.x+ "/"+start.y+")");
		end = new Vector2D(start);
	}	
	public void processPath(){
		if(end == null){
			init();
		}
		show("Doing it.....");
		kartesian = new Vector2D(processKartesianKoordinates((direction-beta), hypo));
		show("Katheten: " +kartesian);
		end = end.sub(kartesian);
		simuLine = new Line2D.Double(start.x, start.y, end.x, end.y);
		if(isIntersected(simuLine, basis.getElements())){
			show("intersected");
			Vector2D cutpoint = this.calculateCutPoint();
			show("Cutpoint: "+cutpoint.toString());
			show("Startpoint: "+start.toString());
			show("Endpoint: "+end.toString());
			if(start.x == cutpoint.x && start.y == cutpoint.y){
				show("start == cutpoint");
				//start = end;
				
				
			}
			else{
				end = cutpoint;
				//zeichne Linie von Startpoint bis Cutpoint
				board.updateSimulation(new Line2D.Double(start.x, start.y, end.x, end.y));
				start = cutpoint;
				show("END: " +end.toString());
				
				
			}
		}
		//später ohne else, wenn abprall klappt
		else{
			show("not intersected");
			board.updateSimulation(new Line2D.Double(start.x, start.y, end.x, end.y));
			show("Start: "+start);
			start = end;
			show("End: "+end);
		}		
	}	
	public Vector2D processKartesianKoordinates(double radian, double hypo){
		
		double a = Math.cos(Math.toRadians(radian))*hypo;
		double b = Math.sin(Math.toRadians(radian))*hypo;
		
		return new Vector2D(a,b);		
	}
	public void reset(){
		direction = 270;
		end = null;
	}
	public boolean isIntersected(Line2D.Double simuLine, Vector<GardenElement>obstacles){
				
		for(GardenElement element : obstacles){
			if(element.getType().equals("Polygon")){
				Polygon p = element.getPolygon();
				//Punkte des Polygons 
				for(int x = 0; x < p.xpoints.length; x++){
					//1. Punkt für Linie
					Point p1  = new Point();
					p1.x = p.xpoints[x];
					p1.y = p.ypoints[x];
					//2. Punkt für Linie
					Point p2 = new Point();
					p2.x = p.xpoints[x+1];
					p2.y = p.ypoints[x+1];
					
					//modelline and simuline
					modelLine = new Line2D.Double(p1.x, p1.y, p2.x, p2.y);
					
					if(simuLine.intersectsLine(modelLine)){
						show("BOOM!! says "+element.getName());
						show("ModellLine: "+modelLine.getP1().toString() +" / " + modelLine.getP2().toString());
						element.printElement();
						if(direction < 0){
							direction += 360;
						}
						else{
							direction -=140;
						}
						show("Direction: "+direction);
						return true;
					}		
					//sonst array out of bounds!
					else if(x == p.xpoints.length-2){
					
					    break;
					}
					else{
					}
				}
			}
		}		
		return false;
	}
	public Vector2D calculateCutPoint(){
		//Punkte der simulierten Linie
		double x1 = simuLine.getX1();
		double y1 = simuLine.getY1();
		double x2 = simuLine.getX2();
		double y2 = simuLine.getY2();
		
		//Steigung der 1. Linie
		double k1 = (y2-y1)/(x2-x1);
		
		//Achsschnitt(y) 1. Linie
		double d1 = y1 - (k1*x1);
			
		//Punkte der geschnittenen Linie (Garten)
		double x3 = modelLine.getX1();
		double y3 = modelLine.getY1();
		double x4 = modelLine.getX2();
		double y4 = modelLine.getY2();
		
		double k2 = 0.0d;
		double d2 = 0.0d;
		double sx = 0.0d;
		double sy = 0.0d;
		
		//Steigung der 2. Linie
		k2 = ((y4 - y3)/(x4 - x3));
		//Achsschnitt(y) 2. Linie
		if(x3 == x4){
			d2 = 0.0;
			sx = x3;
		}
		else{
			d2 = y3 - k2*x3;
			//Schnittpunkt (x)
			sx =((d2 - d1)/(k1 - k2));
		}		
		//Schnittpunkt (y)
		sy = sx*k1 + d1;
		
		//Schnittpunkt (vector)	
		return new Vector2D(sx, sy);
	}
	private void show(String s){
		System.out.println(s);
	}
}
```


----------



## Marco13 (23. Mrz 2012)

Das wird so wohl kaum jemand nachvollziehen (wollen/können).

Kann man nicht ein KSKB basteln, wo nur die Methode

```
Line2D computeReflected(Line2D incoming, Line2D other)
{
   ....
}
```
fehlt?


----------



## HarryG32 (26. Mrz 2012)

Sorry, hab mir fast gedacht, dass dieser Auszug nicht nachvollziehbar ist...

Mittlerweile kann ich den Einfallswinkel berechnen, indem ich bei Intersection zuerst den Schnittpunkt der Linien berechne. Dann berechne ich den Vector (v1) vom Schnittpunkt zum Startpunkt der simulierten Linie und den Vector (v2) vom Schnittpunkt zum Endpunkt einer Linie aus dem Modell(siehe Grafik).

Schnittpunkt & Vektoren

Über das Skalarprodukt rechne ich mir den Einfallswinkel aus...



```
public double processIncidenceAngle(Vector2D cutting, Vector2D start, Vector2D end){
		
		Vector2D v1 = new Vector2D(getDirectionVector(cutting,start));
		Vector2D v2 = new Vector2D(getDirectionVector(cutting, end));
				
		//v1 * v2 
		double length=(v1.x*v2.x)+(v1.y*v2.y);
		
		//betrag v1
		double lengv1 = (v1.x*v1.x)+(v1.y*v1.y);
		
		//betrag v2
		double lengv2 = (v2.x*v2.x)+(v2.y*v2.y);
		
		//betrag v1 * betrag v2
		double lengv3 = lengv1*lengv2;
		
		//länge durch betrag v1*betrag v2^0.5 => ?? 
		double angle = length/ Math.pow(lengv3, 0.5);
		//arkuscosinus des winkels
		angle = Math.acos(angle);
		//bogenmaß in grad
		angle = angle*180/Math.PI;
		
		return angle;
		
	}
```

Warum ich den Betrag hoch 0,5 rechnen muss, weiss ich jetzt nicht genau leider habe ich die Quelle für die Berechnung nicht notiert . Aber so funktioniert es, die Werte stimmen.

Jetzt weiss ich aber nicht genau wie ich den Ausfallswinkel am besten berechne, am besten wäre die Angabe eines neuen Richtungswinkel,  indem ich einen Winkel zwischen 0 und 360 Grad angebe...

Der Startwinkel der Simulation ist z.B.: 270° - alpha (default: 15°), dann habe ich z.B.: einen Einfallswinkel von 60°, wie komme ich auf meinen neuen Richtungswinkel???  

Was mache wenn ich eine Linie schneide, die senkrecht im Koordinatensystem liegt?? Also nicht oben, unten sondern links rechts...

btw: Richtungwinkel: 0 - 360 °, Einfalls- und Ausfallswinkel: 0-90°


----------



## Marco13 (30. Mrz 2012)

x^0.5 ist das gleiche wie wurzel(x) - man sollte eher Math.sqrt(x) schreiben, dann ist klarer, was gemeint ist. 

Ansonsten: Wäre das Problem gelöst, wenn es eine Methode gäbe wie die oben angedeutete "computeReflected"?


----------



## HarryG32 (3. Apr 2012)

Ahh, x^0,5 == Math.sqrt(x)...ist klar, sollte ich eigentlich wissen...:autsch:

Ja, das Problem wäre gelöst, wenn es diese Methode gäbe.

Mittlerweile bin ich schon ein Stück weiter.....

Bei Intersection berechne ich folgendes:

> Schnittpunkt simulierte Linie und Begrenzungslinie (mittels Steigung)
> Winkel zwischen simulierte Linie und Begrenzungslinie (Vektorrechnung) => Einfallswinkel
> Winkel zwischen Normallinie (y1 == y2) und Begrenzungslinie (Vektorrechung) => Winkel d. Begrenzung

Die Winkel verwende ich um den neuen Richtungswinkel (Ausfallswinkel als Polarwinkel) zu berechnen. Dieser hat einen Wert zwischen 0 und 360.  Bei geraden Begrenzungslinie funktioniert es einwandfrei, ist die Begrenzungslinie schräg habe ich noch Probleme, Probleme bekomme ich auch wenn die Linie direkt in eine Ecke rein geht...

Aber prinzipiell weiss ich jetzt wie ich es machen muss, wenn ich keine Maximalwerte (Größe der Gartenfläche ist ja individuell gestaltbar) habe...


----------



## Marco13 (3. Apr 2012)

Vergiß alles, was mit "Steigung" zu tun hat, das ist für "richtige" geometrische Berechnungen vollkommen unbrauchbar. 

Hab' mal das Beispiel von http://www.java-forum.org/awt-swing...-zwischen-objekt-kante-finden.html#post837614 um eine "Reflection"-Klasse erweitert, die die besagte Methode hat. 


```
// Marco13 for [url]http://www.java-forum.org/allgemeine-java-themen/132049-2d-simulation-individuell-gestalbarer-umgebung.html[/url]

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class LineReflectionTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame f = new JFrame();
                PaintPanel paintPanel = new PaintPanel();
                f.getContentPane().add(paintPanel);
                f.setSize(600,600);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }
}


class PaintPanel extends JPanel implements MouseMotionListener
{
    private Line2D wall;
    private Point2D p0;
    private Point2D p1;
    private Line2D reflected;

    public PaintPanel()
    {
        addMouseMotionListener(this);

        wall = new Line2D.Double(50, 50, 300, 500);
        p0 = new Point2D.Float(320, 320);
        p1 = new Point2D.Float(420, 420);
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        g.setColor(Color.BLACK);
        g.draw(wall);

        g.setColor(Color.BLUE);
        paint(g, p0);
        paint(g, p1);
        g.draw(new Line2D.Float(p0, p1));

        if (reflected != null)
        {
            g.setColor(Color.RED);
            g.draw(reflected);
        }

    }

    private static void paint(Graphics g, Point2D p)
    {
        int x = (int)p.getX();
        int y = (int)p.getY();
        g.drawOval(x-2, y-2, 5, 5);
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
        p1.setLocation(e.getPoint());
        reflected = Reflection.computeReflected(new Line2D.Double(p0, p1), wall);
        repaint();
    }
}



class Reflection
{
    public static Line2D computeReflected(Line2D incoming, Line2D wall)
    {
        Point2D intersection = Intersection.computeIntersectionSegmentSegment(
            incoming.getX1(), incoming.getY1(), incoming.getX2(), incoming.getY2(),
            wall.getX1(), wall.getY1(), wall.getX2(), wall.getY2());
        if (intersection == null)
        {
        	return null;
        }
        
        // Wall start- and end point and delta
        double wx0 = wall.getX1();
        double wy0 = wall.getY1();
        double wx1 = wall.getX2();
        double wy1 = wall.getY2();
        double wdx = wx1 - wx0;
        double wdy = wy1 - wy0;

        // Incoming start- and end point and delta
        double ix0 = incoming.getX1();
        double iy0 = incoming.getY1();
        double ix1 = incoming.getX2();
        double iy1 = incoming.getY2();
        double idx = ix1 - ix0;
        double idy = iy1 - iy0;

        // Compute angle between wall and incoming line 
        double wLen = Math.sqrt(wdx*wdx+wdy*wdy);
        double iLen = Math.sqrt(idx*idx+idy*idy);
        double dot = dot(idx/iLen, idy/iLen, wdx/wLen, wdy/wLen);
        double angRad = Math.acos(dot);

        // Reflected segment
        double ix = intersection.getX();
        double iy = intersection.getY();
        double rdx = incoming.getX2() - ix;
        double rdy = incoming.getY2() - iy;
        
        // Compute end point of reflected segment 
        double ca = Math.cos(-angRad*2);
        double sa = Math.sin(-angRad*2);
        double rex = ix + ca * rdx - sa * rdy;
        double rey = iy + sa * rdx + ca * rdy;

        // Return result
        Line2D reflectedPart = new Line2D.Double(
        		ix, iy, rex, rey);
        return reflectedPart;
    }
    
    private static double dot(double x0, double y0, double x1, double y1)
    {
    	return x0 * x1 + y0 * y1;
    }
}



/**
 * Utility class for computing intersections between lines and line segments.
 */
class Intersection
{
    /**
     * Epsilon for floating point computations
     */
    private static final double epsilon = 1e-6f;

    /**
     * Computes the intersection of the specified line segments and returns
     * the intersection point, or <code>null</code> if the line segments do
     * not intersect.
     *
     * @param s0x0 x-coordinate of point 0 of line segment 0
     * @param s0y0 y-coordinate of point 0 of line segment 0
     * @param s0x1 x-coordinate of point 1 of line segment 0
     * @param s0y1 y-coordinate of point 1 of line segment 0
     * @param s1x0 x-coordinate of point 0 of line segment 1
     * @param s1y0 y-coordinate of point 0 of line segment 1
     * @param s1x1 x-coordinate of point 1 of line segment 1
     * @param s1y1 y-coordinate of point 1 of line segment 1
     * @param location Optional location that stores the
     * relative location of the intersection point on
     * the given line segments
     * @return The intersection point, or <code>null</code> if
     * there is no intersection.
     */
    public static Point2D computeIntersectionSegmentSegment(
        double s0x0, double s0y0,
        double s0x1, double s0y1,
        double s1x0, double s1y0,
        double s1x1, double s1y1)
    {
        Point2D location = new Point2D.Double();
        Point2D result = computeIntersectionLineLine(
            s0x0, s0y0, s0x1, s0y1, s1x0, s1y0, s1x1, s1y1, location);
        if (location.getX() >= 0 && location.getX() <= 1.0 &&
            location.getY() >= 0 && location.getY() <= 1.0)
        {
            return result;
        }
        return null;
    }


    /**
     * Computes the intersection of the specified lines and returns the
     * intersection point, or <code>null</code> if the lines do not
     * intersect.
     *
     * Ported from
     * [url]http://www.geometrictools.com/LibMathematics/Intersection/[/url]
     *     Wm5IntrSegment2Segment2.cpp
     *
     * @param s0x0 x-coordinate of point 0 of line segment 0
     * @param s0y0 y-coordinate of point 0 of line segment 0
     * @param s0x1 x-coordinate of point 1 of line segment 0
     * @param s0y1 y-coordinate of point 1 of line segment 0
     * @param s1x0 x-coordinate of point 0 of line segment 1
     * @param s1y0 y-coordinate of point 0 of line segment 1
     * @param s1x1 x-coordinate of point 1 of line segment 1
     * @param s1y1 y-coordinate of point 1 of line segment 1
     * @param location Optional location that stores the
     * relative location of the intersection point on
     * the given line segments
     * @return The intersection point, or <code>null</code> if
     * there is no intersection.
     */
    public static Point2D computeIntersectionLineLine(
        double s0x0, double s0y0,
        double s0x1, double s0y1,
        double s1x0, double s1y0,
        double s1x1, double s1y1,
        Point2D location)
    {
        double dx0 = s0x1 - s0x0;
        double dy0 = s0y1 - s0y0;
        double dx1 = s1x1 - s1x0;
        double dy1 = s1y1 - s1y0;

        double len0 = Math.sqrt(dx0*dx0+dy0*dy0);
        double len1 = Math.sqrt(dx1*dx1+dy1*dy1);

        double dir0x = dx0 / len0;
        double dir0y = dy0 / len0;
        double dir1x = dx1 / len1;
        double dir1y = dy1 / len1;

        double c0x = s0x0 + dx0 * 0.5;
        double c0y = s0y0 + dy0 * 0.5;
        double c1x = s1x0 + dx1 * 0.5;
        double c1y = s1y0 + dy1 * 0.5;

        double cdx = c1x - c0x;
        double cdy = c1y - c0y;

        double dot = dotPerp(dir0x, dir0y, dir1x, dir1y);
        if (Math.abs(dot) > epsilon)
        {
            double dot0 = dotPerp(cdx, cdy, dir0x, dir0y);
            double dot1 = dotPerp(cdx, cdy, dir1x, dir1y);
            double invDot = 1.0/dot;
            double s0 = dot1*invDot;
            double s1 = dot0*invDot;
            if (location != null)
            {
                double n0 = (s0 / len0) + 0.5;
                double n1 = (s1 / len1) + 0.5;
                location.setLocation(n0, n1);
            }
            double x = c0x + s0 * dir0x;
            double y = c0y + s0 * dir0y;
            return new Point2D.Double(x,y);
        }
        return null;
    }

    /**
     * Returns the perpendicular dot product, i.e. the length
     * of the vector (x0,y0,0)x(x1,y1,0).
     *
     * @param x0 Coordinate x0
     * @param y0 Coordinate y0
     * @param x1 Coordinate x1
     * @param y1 Coordinate y1
     * @return The length of the cross product vector
     */
    private static double dotPerp(double x0, double y0, double x1, double y1)
    {
        return x0*y1 - y0*x1;
    }

    /**
     * Private constructor to prevent instantiation
     */
    private Intersection()
    {
    }
}
```


----------



## HarryG32 (4. Apr 2012)

> Vergiß alles, was mit "Steigung" zu tun hat, das ist für "richtige" geometrische Berechnungen vollkommen unbrauchbar.



Da gebe ich dir recht! Ich hab in der Ausgabe gemerkt, dass der Schnittpunkt nicht immer 100%ig genau berechnet wurde. Bei einer geraden Linie mit x1 == x2, war die x-Koordinate des Schnittpunkts nicht immer gleich den x-Werten. Die Abweichung ist zwar nur sehr gering, könnte aber dennoch zu Problemen führen....

Danke für dein Beispiel, ich bin jetzt leider noch nicht dazu gekommen es auszuprobieren, muss heute noch was für den Theorieteil fertig schreiben. Morgen werde ich es testen und dir ein Feedback geben....

btw: Dass sich jemand die Mühe macht und ein KSKB mit 300 Zeilen Code schreibt, TOP!!! :toll:


----------



## FerFemNemBem (4. Apr 2012)

Halloechen,



HarryG32 hat gesagt.:


> btw: Dass sich jemand die Mühe macht und ein KSKB mit 300 Zeilen Code schreibt, TOP!!! :toll:




damit ist es dann kein KSKB sondern "nur" noch ein SKB. 

Aber was ich eigentlich wollte: ist Dir aufgefallen, dass Deine Kollisionserkennung nicht korrekt funktioniert? Der Maeher haut immer mal ab:







Gruss, FFNB.


----------



## HarryG32 (6. Apr 2012)

> ...ist Dir aufgefallen, dass Deine Kollisionserkennung nicht korrekt funktioniert?



Ja, das weiss ich, muss die Ausnahmebehandlung noch verbessern. Wenn der Mäher in die Ecke reinfährt, ist er weg.


----------



## HarryG32 (11. Apr 2012)

Hallo,

dein SKB funktioniert super! Leider weiss ich jetzt nicht genau wie ich es in mein Beispiel einbauen soll. Ich arbeite nämlich mit Polarwinkeln (0-360°), die die neue Richtung bei Intersection (= Ausfallswinkel) vorgeben. Ich starte mit einem Polarwinkel von 255° ändere diesen bei jeder Intersection entsprechend (was leider noch nicht 100%ig funktioniert).

Bei der Berechnung des Schnittpunktes blicke ich auch nicht ganz durch (für was braucht man "Point2D location = new Point2D.Double()" ??), mit der Steigung funktioniert das relativ einfach, leider ist es nicht so zuverlässig. ?? Ich denke aber, dass ich diesen Code für meine Berechnungen verwenden kann, solange ich nix im Code ändern muss...

Leider sind meine mathematischen Kenntnisse in diesem Bereich nicht fundiert, ich komme aus der Finanzmathematik...

Danke für deine Unterstützung!


----------



## Marco13 (11. Apr 2012)

Die Schnittpunktberechnung ist auch nur portiert (siehe Link im Kommentar). Das "wichtige" ist, dass diese Funktionen als Utilities angeboten werden und überall aufgerufen werden können. Notfalls könnte man auch immer zwischen Polar- und Kartesischen Koordinaten hin-und-her konvertieren, um die Methode aufrufen zu können, aber es wäre natürlich schön, wenn man das nicht müßte. Warum eigentlich Polarwinkel?


----------



## HarryG32 (11. Apr 2012)

@Polarwinkel: Mein Professor meinte, dass ich es so lösen soll, der Ausfallswinkel sollte immer gleich dem Einfallswinkel sein.


----------



## HarryG32 (11. Apr 2012)

Übrigens, bei der Intersection muss ich einen Vector mit Polygonen durchlaufen und jede Linie überprüfen. Wo bau ich das am besten ein, in der Utility-Klasse oder in der Hauptklasse?? Und in der Utility-Klasse übergebe ich die Linie, wo ich weiss, dass sie geschnitten wurde und lasse Schnittpunkt berechnen...


Die Frage hat sich erledigt, hab dazu eh schon eine Funktion in der Hauptklasse, ausserdem wird in der Utility-Klasse immer ein Schnittpunkt berechnet, wie die Ausgabe gezeigt hat...


----------



## Marco13 (11. Apr 2012)

Es wird nicht immer ein Schnittpunkt berechnet: Wenn die Linien Parallel sind, kommt "null" zurück. (Man könnte auch irgendeinen Point mit Double.NaN oder Double.POSITIVE_INFINITY oder so verwenden, aber 'null' fand ich hier sinnvoller). 

Beachte, dass es zwei Methoden gibt, einmal für den Schnitt zwischen Linien und einmal für den Schnitt zwischen Liniensegmenten - du wirst vermutlich eher letzteres brauchen.

Zu den Polygonen und Vectoren: Schau nochmal im oben verlinkten Thread, wo ich die Intersection-Klasse zuerst gepostet hatte: http://www.java-forum.org/awt-swing...-zwischen-objekt-kante-finden.html#post837614


----------

