# Schnittpunkt zwischen Objekt und Kante finden



## propra (6. Dez 2011)

Hallo zusammen,

wie der Titel es schon sagt, bin ich auf der Suche nach einem Weg, wie man den Schnittpunkt von Objekten und Kanten findet.
Ich kann Objekte zeichnen (Kreise und Rechtecke) und diese miteinander verbinden. Es wird dann eine Linie mit 
	
	
	
	





```
drawLine()
```
 vom Mittelpunkt des einen Objektes zum anderen gezeichnet.
Damit ich aus der bisher ungerichteten Kante eine gerichtete machen kann, muss ich eine Pfeilspitze hinzufügen. Die Spitze soll am Rand des Objektes enden.
Hat jemand einen kleinen Tipp für mich, wonach ich suchen könnte?

Vorab vielen Dank


----------



## bERt0r (6. Dez 2011)

Ich bin zwar kein Obermathematiker, aber ich hab dir mal eine kleine Zeichnung gemacht wie man das ausrechnen könnte (ohne gewähr)
Anhang anzeigen 3788


----------



## propra (6. Dez 2011)

Vielen Dank für die Zeichnung.



bERt0r hat gesagt.:


> Ich bin zwar kein Obermathematiker


Dann sind wir ja schon zu zweit. 

Ich hätte da noch ein paar Fragen und glaube das mir da auch noch etwas mathematischer Background fehlt.
Was wären den ein paar Stichpunkte, die mir weiterhelfen würde mich ins Thema einzuarbeiten.


----------



## Marco13 (6. Dez 2011)

Falls die Objekte, um die es geht, als "Shape" vorliegen, kann man mit einem PathIterator (am einfachsten: Einem FlatteningPathIterator) über den Rand laufen und jedes Liniensegment mit dem gegebenen Liniensegment schneiden, z.B. mit "findLineSegmentIntersection" von Geometry.java oder, wenn man keine GPL will und keine andere Implementierung findet, indem man die entsprechenden Methoden von Geometric Tools: Intersection portiert (ist meistens nicht so kompliziert)


----------



## andi_help (7. Dez 2011)

Stell doch eine Geradengleichung zwischen den beiden Punkten auf. Dadurch bekommst den Steigungskoeffizienten m. Dann gilt tan(alpha)=m, also mal den Winkel alpha ausrechnen.
Mit den Formeln 
x1=x_koordinate_mittelpunktkreis + radius*cos(alpha)
y1=y_koordinate_mittelpunktkreis + radius*sin(alpha)
bekommst den einen Schnittpunkt der Geraden mit dem Kreis. Für den anderen einfach + durch - ersetzen.


----------



## propra (7. Dez 2011)

Hallo zusammen,

vielen Dank für die Antworten.



Marco13 hat gesagt.:


> Falls die Objekte, um die es geht, als "Shape" vorliegen, kann man mit einem PathIterator (am einfachsten: Einem FlatteningPathIterator) über den Rand laufen und jedes Liniensegment mit dem gegebenen Liniensegment schneiden, z.B. mit "findLineSegmentIntersection" von Geometry.java oder, wenn man keine GPL will und keine andere Implementierung findet, indem man die entsprechenden Methoden von Geometric Tools: Intersection portiert (ist meistens nicht so kompliziert)



Ich darf leider nur Klassen aus der Standardbibliothek benutzen. Wenn ich die Links richtig gedeutet habe, handelt es sich ja dabei um externe Dateien, die ich in mein Projekt einbinden muss. Somit hilft mir der Hinweis leider nicht weiter. Trotzdem Danke.



andi_help hat gesagt.:


> Stell doch eine Geradengleichung zwischen den beiden Punkten auf. Dadurch bekommst den Steigungskoeffizienten m. Dann gilt tan(alpha)=m, also mal den Winkel alpha ausrechnen.
> Mit den Formeln
> x1=x_koordinate_mittelpunktkreis + radius*cos(alpha)
> y1=y_koordinate_mittelpunktkreis + radius*sin(alpha)
> bekommst den einen Schnittpunkt der Geraden mit dem Kreis. Für den anderen einfach + durch - ersetzen.



Vielen Dank für die Formel. Wenn ich sie richtig verstehe, dann funktioniert sie für den Kreis. Ich habe aber auch noch Rechtecke als mögliche Symbole, wo ich eine entsprechende Berechnung durchführen muss.
Ich würde auch gerne verstehen, was die Formel hier genau macht. Also wäre ich für weitere Stichworte oder Erklärungen sehr dankbar.

Als weiteren Hinweis habe ich gestern noch erhalten, dass sich die Berechnung mit Hilfe der Strahlensätze und des Satz des Pythagoras lösen lassen soll. Daraufhin habe ich mir die Wikipediaartikel dazu angesehen, aber inwieweit mir das helfen soll, habe ich nicht erkennen können.


----------



## Marco13 (7. Dez 2011)

Wenn jemand vorschlägt, für geometrische Berechnungen (in diesem Sinne) die "Steigung" zu verwenden, läuft es mir immer kalt den Rücken runter... :noe: Die verlinkte Datei enthält viele Methoden, aber eigentlich brauchst du davon nur eine - nämlich die zur Berechnung des Schnittpunktes zwischen zwei Liniensegmenten (gegeben durch jeweils zwei Punkte). Du könntest dir auch mal http://www.java-forum.org/spiele-mu...iniges-geometrie-punkte-vektoren-geraden.html durchlesen... auch wenn die Schnittpunktberechnung dort nicht direkt so beschrieben ist, wie du sie brauchst....


----------



## bERt0r (7. Dez 2011)

Oder dir meine Zeichnung nochmal ansehen, denn genau das ist der Strahlensatz (ähnliche Dreiecke).
BX soll übrigens die Strecke von B nach X darstellen, falls das nicht zu erkennen war.


----------



## propra (7. Dez 2011)

Danke, den Beitrag von Beni hatte ich auch schon gefunden, aber habe da auch nicht viel von mitnehmen können, was mir bei der Berechnung weiterhelfen könnte. Besser gesagt, habe ich nicht erkannt, was mir da weiterhelfen könnte.
Ich glaube mir fehlt in erster Linie überhaupt eine Vorstellung, was bei der Berechnung überhaupt ablaufen soll.


----------



## propra (8. Dez 2011)

bERt0r hat gesagt.:


> Oder dir meine Zeichnung nochmal ansehen, denn genau das ist der Strahlensatz (ähnliche Dreiecke).
> BX soll übrigens die Strecke von B nach X darstellen, falls das nicht zu erkennen war.



Hallo zusammen,

ich habe mir die Zeichnung nun noch einmal genauer angesehen und mir Gedanken darüber gemacht, was ich habe und was ich haben möchte.
Die Punkte A und K habe ich genauso wie ich die Länge der Strecken AB und KY habe.
Jetzt hatte ich mir überlegt, dass ich den Punkt C erhalte, indem ich die Y-Koordinate des Punktes A und die X-Koordinate vom Punkt K nehme.
Aber mit dem Rest komme ich irgendwie nicht klar. Jetzt habe ich ja Geraden in der Formel.
Wie würde ich die in die Berechnung einfließen lassen?  
Ist es richtig, dass mein nächster Schritt aus der letzten Zeile (BX = CK*AB/AC) besteht?


----------



## bERt0r (8. Dez 2011)

Du musst dir zuerst alpha ausrechnen, damit du im Fall vom Quadrat, weißt welche Seite die Gerade schneidet. Stell dir vor, der Kreis wäre weiter oben, dann würde die Linie durch die Obere Seite gehen und das Dreieck müsste nach obene (Y-Achse) gehen.


----------



## Marco13 (8. Dez 2011)

Wie das bei zwei Qudraten oder zwei Kreisen laufen soll, und wie man die Fallunterscheidungen für die einzelnen Seiten des Quadrats vernünftig machen soll, ist mir nicht klar, aber anscheinend ist das ja nicht von Interesse....


----------



## bERt0r (8. Dez 2011)

Naja, die Objekte müssen eine Methode bereitstellen, mit der der Punkt an dem die Linie den Rand des Objekts trifft berechnet wird. Als übergabeparameter gibts den Mittelpunkt vom anderen Objekt.
Mittelpunkt von this nach Parameter= Gerade
Und je nach Form den Punkt X ausrechnen. Das ganze geht beim Kreis beispielsweise viel einfacher.

Bzgl Fallunterscheidung der Seiten: 
Fall Quadrat: Wenn du das Dreieck so wie in der Zeichnung auf der X-Achse aufziehst und der Winkel alpha>45 ist, geht die Linie nicht mehr durch die Rechte Seite des Quadrats, sondern durch die Obere.

Für ein Rechteck lässt sich das sicher auch berechnen, dafür hab ich aber keine Zeit mehr


----------



## propra (8. Dez 2011)

bERt0r hat gesagt.:


> Du musst dir zuerst alpha ausrechnen, damit du im Fall vom Quadrat, weißt welche Seite die Gerade schneidet. Stell dir vor, der Kreis wäre weiter oben, dann würde die Linie durch die Obere Seite gehen und das Dreieck müsste nach obene (Y-Achse) gehen.



Nachdem ich nun ein wenig recherchiert habe, muss ich dafür die Länge der Gegenkathete durch die der Ankathete teilen.
In meinem Fall wäre das dann Länge von CK durch Länge von AC. Aber wie berechne ich dass nun mit den mir vorhandenen Informationen?

Die Strecke CK habe ich durch die 4 Punkte c.x, c.y, k.x und k.y gegeben. AC durch a.x, a.y, c.x und c.y. 
Rechne ich nun (c.x/a.x) + (c.y/a.y) +(k.x/c.x) + (k.y/c.y) ?

Nachdem man Gegenkathete durch Ankathete geteilt hat muss man noch die Arcustangens-Funktion auf das Ergebnis anwenden und dann erhält man den Winkel in °.
Meine Frage ist nun, ob ich oben die Katheten richtig teile bzw. wie ich die Länge einer Strecke aus den gegebenen Punkten berechne.

Wäre schön, wenn jemand da eine kurzes Feedback zu geben könnte.



Marco13 hat gesagt.:


> Wie das bei zwei Qudraten oder zwei Kreisen laufen soll, und wie man die Fallunterscheidungen für die einzelnen Seiten des Quadrats vernünftig machen soll, ist mir nicht klar, aber anscheinend ist das ja nicht von Interesse....



Verstehe ich es richtig, dass Du es anders machen würdest? Was wäre deine Vorgehensweise?


----------



## propra (8. Dez 2011)

Mittlerweile habe ich die Berechnung des Winkels hinbekommen.
Zumindest auf dem Papier. Mal schauen, ob sich dies nun auch schön in eine Methode gießen lässt.


----------



## Marco13 (8. Dez 2011)

propra hat gesagt.:


> Verstehe ich es richtig, dass Du es anders machen würdest? Was wäre deine Vorgehensweise?



_Richtig_, natürlich :smoke:  

Ich brauch' sowas ähnliches vermutlich auch demnächst, deswegen hab' ich mal was gebastelt

```
import java.awt.geom.Point2D;

/**
 * Utility class for computing intersections between lines and line segments.
 */
public 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()
    {
    }
}
```

Und ein kleiner Test dazu

```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

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

public class ShapeIntersectionTest
{
    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 Shape shape;
    private Point2D p0;
    private Point2D p1;
    private List<Point2D> intersections = new ArrayList<Point2D>();
    
    public PaintPanel()
    {
        addMouseMotionListener(this);
        
        Path2D path = new Path2D.Float();
        path.moveTo(200,200);
        path.lineTo(300,200);
        path.lineTo(250,250);
        path.lineTo(300,300);
        path.lineTo(200,300);
        path.closePath();
        
        AffineTransform at = AffineTransform.getRotateInstance(0.2, 120, 280);
        Shape s = at.createTransformedShape(new Ellipse2D.Double(100,250, 40, 80));
        path.append(s, false);
        shape = path;
        
        p0 = new Point2D.Float(220, 220);
        p1 = new Point2D.Float(320, 220);
    }
    
    @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(shape);
        g.drawString("Intersections:", 10, 20);
        for (int i=0; i<intersections.size(); i++)
        {
            g.drawString(String.valueOf(intersections.get(i)), 10, 40+i*20);
        }
        
        g.setColor(Color.BLUE);
        paint(g, p0);
        paint(g, p1);
        g.draw(new Line2D.Float(p0, p1));
        
        for (Point2D intersection : intersections)
        {
            g.setColor(Color.RED);
            paint(g, intersection);
        }
        
    }

    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)
    {
        p0.setLocation(e.getPoint());
        
        intersections.clear();
        PathIterator pi = shape.getPathIterator(null, 0.1);
        double coords[] = new double[6];
        Point2D firstPoint = new Point2D.Double();
        Point2D previousPoint = new Point2D.Double();
        Point2D intersection = null;
        while (!pi.isDone())
        {
            switch (pi.currentSegment(coords))
            {
                case PathIterator.SEG_MOVETO:
                    firstPoint.setLocation(coords[0], coords[1]);
                    previousPoint.setLocation(firstPoint);
                    break;
                    
                case PathIterator.SEG_LINETO:
                    intersection = Intersection.computeIntersectionSegmentSegment(
                        previousPoint.getX(), previousPoint.getY(), 
                        coords[0], coords[1],
                        p0.getX(), p0.getY(), 
                        p1.getX(), p1.getY());
                    previousPoint.setLocation(coords[0], coords[1]);
                    if (intersection != null)
                    {
                        intersections.add(intersection);
                    }
                    break;
                    
                case PathIterator.SEG_CLOSE:
                    intersection = Intersection.computeIntersectionSegmentSegment(
                        previousPoint.getX(), previousPoint.getY(), 
                        firstPoint.getX(), firstPoint.getY(), 
                        p0.getX(), p0.getY(), 
                        p1.getX(), p1.getY());
                    previousPoint.setLocation(coords[0], coords[1]);
                    if (intersection != null)
                    {
                        intersections.add(intersection);
                    }
                    break;
                    
            }
            pi.next();
        }
        
        repaint();
    }
    
    
}
```


----------



## propra (9. Dez 2011)

Erst einmal danke für die Mühe, die Du dir gemacht hast und Respekt, wenn du das mal eben gebastelt hast.
Ich finde deine Lösung super und sie macht auch genau das, was ich brauche, nur sehe ich da das Problem, dass ich auch erklären muss, was die einzelnen Klassen und Methoden leisten.

Des Weiteren hast Du auch die Methode 
	
	
	
	





```
computeIntersctionLineLine()
```
 aus einem anderen Paket als der Standardbibliothek übernommen. Deshalb müsste ich auch erst einmal nachfragen, ob ich das überhaupt dürfte.

Ich habe auch nur die Anforderung Kanten zwischen Rechtecken und Kreisen oder Kreisen und Rechtecken zu zeichnen. Das Verbinden gleicher Symbole entfällt.

Dein Ansatz ist bestimmt der, welcher mehr Flexibilität bietet, aber in meinem Fall geht es erst einmal nur darum ein erstes Projekt selbstständig umzusetzen und erste Erfahrungen zu sammeln.

Ich glaube, dass der Ansatz von bERt0r für meine Zwecke ausreichend ist, weshalb ich ihn auch gerne weiter verfolgen würde.

Hier mal meine Methode, die den Startpunkt berechnen soll.

```
private void calculateStartPoint(Node startNode, Node endNode, Graphics2D g2d) {
		
		int startNodeY = startNode.getY();
		int endNodeX = endNode.getX();

		//Zeichnet Punkt C
		Point c = new Point(endNodeX-1, startNodeY-1);
		g2d.fillOval(c.x, c.y, 3, 3);
		
		Point a = new Point(startNode.getX(), startNode.getY());
		Point k = new Point(endNode.getX(), endNode.getY());
		
		// Winkel berechnen
		int lengthSideAdjacentToAlpha = Math.abs(c.x - a.x);
		int lengthSideOppositeOfAlpha = Math.abs(c.y - k.y);		
		
		double tanAlpha = (double) lengthSideOppositeOfAlpha / (double) lengthSideAdjacentToAlpha;
		
		double antanTanAlpha = Math.atan(tanAlpha);

		double degrees = Math.toDegrees(antanTanAlpha);
		//Ende Winkel berechnen
		
		//Länge BX (auf Aussenkante) berechnen
		double radius = 16.0;

		double lengthBX = lengthSideOppositeOfAlpha * ( radius / lengthSideAdjacentToAlpha);
		
		// Länge Hypothenuse berechnen
		double lengthHypotenuse = Math.sqrt((radius * radius) + (lengthBX * lengthBX));

		System.out.println("Länge Hypotenuse = " + lengthHypotenuse);
	}
```

Jetzt müsste ich die Länge der Hypotenuse auf meiner Linie "zurück laufen" und dann hätte ich den Startpunkt gefunden. Hat jemand eine Idee, wie ich dies bewerkstelligen kann?
Ich würde gerne mal den Punkt zu Demonstrationszwecken einzeichnen und schauen, ob er sich an der Außenkante des Objektes bewegt, wenn ich das andere hoch und runter bewege.


----------



## bERt0r (9. Dez 2011)

Nur damit das klar ist, meine Zeichnung und die Gleichung dienen nur dazu den Punkt am Rechteck zu errechnen. Der Pfeil ginge in dem Beispiel vom Kreis auf das Rechteck.
Ich weis jetzt nicht was Node ist, org.w3c.dom.Node glaube ich aber nicht. Entweder du benutzt Shapes um deine Objekte zu speichern, da gibts die Klassen Rectangle2D und Ellipse2D, die unterstützen dann auch sachen wie intersects.
Oder wenn du das nicht darfst, mach dir eine Klasse Kreis und eine Klasse Rechteck.
Jedenfalls würde ich ein eine Interface TargetOfArrow oder so erstellen, darin eine Methode Point errechnePunktDesPfeils(Point puntAufDerGeraden) erstellen und dieses Interface in meinen gewählten Klassen implementieren. Wenn du dann zeichnest und du hast einen Pfeil von Form a auf Form b, rufst du b.errechnePunktDesPfeils(a.mittelpunkt) auf.


----------



## propra (11. Dez 2011)

bERt0r hat gesagt.:


> Nur damit das klar ist, meine Zeichnung und die Gleichung dienen nur dazu den Punkt am Rechteck zu errechnen. Der Pfeil ginge in dem Beispiel vom Kreis auf das Rechteck.
> Ich weis jetzt nicht was Node ist, org.w3c.dom.Node glaube ich aber nicht. Entweder du benutzt Shapes um deine Objekte zu speichern, da gibts die Klassen Rectangle2D und Ellipse2D, die unterstützen dann auch sachen wie intersects.
> Oder wenn du das nicht darfst, mach dir eine Klasse Kreis und eine Klasse Rechteck.



Shapes dürfte ich benutzen. Hatte es aber bisher so, dass ich eigenständige Klassen mit einer Methode 
	
	
	
	





```
drawSymbol()
```
 habe, die dann von 
	
	
	
	





```
paintComponent()
```
 aufgerufen wird. Die Klassen sollen aber nicht nur die Symbole darstellen, sondern auch noch andere Informationen beinhalten. Ich denke, deshalb kommt Shape für mich  nicht in Frage.



bERt0r hat gesagt.:


> Jedenfalls würde ich ein eine Interface TargetOfArrow oder so erstellen, darin eine Methode Point errechnePunktDesPfeils(Point puntAufDerGeraden) erstellen und dieses Interface in meinen gewählten Klassen implementieren. Wenn du dann zeichnest und du hast einen Pfeil von Form a auf Form b, rufst du b.errechnePunktDesPfeils(a.mittelpunkt) auf.



Das versteh ich noch nicht ganz, deshalb muss ich noch einmal nachfragen.
TargetOfArrow soll dann den Schnittpunkt darstellen?
Die Methode 
	
	
	
	





```
errechnePunktDesPfeils(Point punktAufDerGeraden)
```
 berechnet dann den Zielpunkt?



			
				propra hat gesagt.:
			
		

> Jetzt müsste ich die Länge der Hypotenuse auf meiner Linie "zurück laufen" und dann hätte ich den Startpunkt gefunden. Hat jemand eine Idee, wie ich dies bewerkstelligen kann?



Hierzu habe ich mittlerweile eine "Lösung" gefunden. Allerdings funktioniert sie nur im Winkel zwischen 0° und 45° richtig.
Kann es sein, ich erst einmal feststellen muss, ob sich das Ursprungsobjekt auch rechts oberhalb befindet?
Wenn nicht, dann muss doch die Berechnung angepasst werden, oder?
Ich weiß jetzt nicht, ob ich da einen Denkfehler drin habe. Wäre schön, wenn jemand dazu einen Tipp hätte.


----------



## bERt0r (11. Dez 2011)

bERt0r hat gesagt.:


> Bzgl Fallunterscheidung der Seiten:
> Fall Quadrat: Wenn du das Dreieck so wie in der Zeichnung auf der X-Achse aufziehst und der Winkel alpha>45 ist, geht die Linie nicht mehr durch die Rechte Seite des Quadrats, sondern durch die Obere.


Das heisst das Dreieck muss je nach Winkel auf der x oder der y Achse aufgezogen werden.


----------



## propra (11. Dez 2011)

Reicht diese Unterscheidung denn auch aus, wenn sich der Kreis nun links unterhalb vom Rechteck befinden würde?


----------



## bERt0r (11. Dez 2011)

Das sollte es, da du aber geschrieben hast, du rechnest die Hypotenuse zurück stimmts dann eventuell nicht mehr: (-1)^2=1


----------



## propra (11. Dez 2011)

Mittlerweile habe ich es so gemacht, dass ich die Punkte B und X durch die Längen der Strecken AB und BX finde.
Dann müsste ich das je nach Fall auch wieder anpassen.
Vielen Dank erst einmal. Werde es mal ausprobieren und dann ein Feedback geben.


----------



## propra (15. Dez 2011)

andi_help hat gesagt.:


> Stell doch eine Geradengleichung zwischen den beiden Punkten auf. Dadurch bekommst den Steigungskoeffizienten m. Dann gilt tan(alpha)=m, also mal den Winkel alpha ausrechnen.
> Mit den Formeln
> x1=x_koordinate_mittelpunktkreis + radius*cos(alpha)
> y1=y_koordinate_mittelpunktkreis + radius*sin(alpha)
> bekommst den einen Schnittpunkt der Geraden mit dem Kreis. Für den anderen einfach + durch - ersetzen.



Hallo zusammen,

hiermit habe ich noch etwas Probleme.
Probiere nun schon seit 1-2 Tagen herum, aber irgendwie scheint noch irgendwo ein Fehler zu stecken.


```
private void calculateEndPoint() {

		tangent = Math.toRadians(tangent);
		System.out.println("Tangens.toRadians = " + tangent);

		endPoint = new Point();

		if (centerStartNode.x < centerEndNode.x
				&& centerStartNode.y > centerEndNode.y) {
			//Hier muss noch ein Fehler sein
			System.out.println("Stelle rechts oberhalb von Transition");

			endPoint.x = centerEndNode.x + ((int) (radius * Math.cos(tangent)));

			endPoint.y = centerEndNode.y + ((int) (radius * Math.sin(tangent)));
		}

		if (centerStartNode.x < centerEndNode.x
				&& centerStartNode.y < centerEndNode.y) {
			System.out.println("Kreis rechts unterhalb von Rechteck");

			endPoint.x = centerEndNode.x - ((int) (radius * Math.cos(tangent)));

			endPoint.y = centerEndNode.y - ((int) (radius * Math.sin(tangent)));
		}

		if (centerStartNode.x > centerEndNode.x
				&& centerStartNode.y < centerEndNode.y) {
			//Hier muss noch ein Fehler sein
			System.out.println("Kreis links unterhalb von Rechteck");


			endPoint.x = centerEndNode.x - ((int) (radius * Math.cos(tangent)));

			endPoint.y = centerEndNode.y - ((int) (radius * Math.sin(tangent)));

		}

		if (centerStartNode.x > centerEndNode.x
				&& centerStartNode.y > centerEndNode.y) {
			System.out.println("Kreis links oberhalb von Rechteck");

			endPoint.x = centerEndNode.x + ((int) (radius * Math.cos(tangent)));

			endPoint.y = centerEndNode.y + ((int) (radius * Math.sin(tangent)));
		}
	}
```

Hat jemand eine Idee, wo der Fehler liegen könnte?
Leider kann ich nicht mehr sagen, als das es nicht funktioniert, da ich kein Muster erkennen kann, was falsch läuft.
Als Winkel benutze ich den Winkel, den ich bei der Berechnung des Schnittpunktes für das Rechteck verwendet habe. Es müsste ja derselbe sein. Ich habe keine Ahnung, wie ich es nun schaffe, dass der Schnittpunkt "auf die andere Seite" wandert.
Damit besser erkannt wird, was falsch läuft, hänge ich mal ein Bild an.
Vorab vielen Dank.


----------



## propra (15. Dez 2011)

Hallo zusammen,

mittlerweile habe ich den Fehler selber gefunden.
In den beiden Methoden, wo ich den Fehler vermutet habe, musste ich noch eine Änderung am Winkel berechnet werden. Der Winkel musste von 180° abgezogen werden. Danach funktioniert es.
Bei der Gelegenheit wollte ich mich auch noch bei allen, die zur Lösung beigetragen haben bedanken.
Insbesondere bERt0r hat ja sehr viel Ausdauer bewiesen. 
Also noch einmal vielen Dank an alle und bis zum nächsten Mal.

propra


----------

