Punkt um ein Rotationszentrum rotieren lassen

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Moin Moin!

Ich zeichne mit der Methode drowLine(x1, x1, x2, x2) des Graphics-Objekt eine Linie. Jetzt möchte ich diese Linie um ein Rotationszentrum mit den Koordinaten x_rz und y_rz um grad Grad rotieren lassen.

So wie ich mir das gerade vorstelle, benötige ich eine Funktion, die die beiden Punkte x1,y1 und x2,y2 jeweils um grad Grad um das Rotationszentrum x_rz,y_rz rotieren lässt. Mit den neuen Koordinaten für die beiden Punkte lasse ich dann mit drawLine() eine neue Linie zeichnen.

Gibt es irgendwo eine solche Funktion? ... oder muss ich sowas selbst schreiben. Für letzteren Fall: Wie wäre mathematisch der einfachste Weg?

Freue mich auf eure Antworten!
 
G

Guest

Gast
1) Zum Koordinatenursprung transformieren
2) Rotieren
3) Rücktransformieren
4) Ausgeben

Alles klar? :wink:
 
G

Guest

Gast
Nein, überhaupt nicht. Bin Anfänger und benötige eine etwas verständlichere und ausführlichere Erläuterung. ;-)
 

0x7F800000

Top Contributor
ich nehme mal an dass du nicht mit diesen Graphics2D arbeitest, und keine affine transformationen einsetzst? dann würde wohl einfach sowas reichen: das eine ende des striches lässt du im zentrum, das andere ende berechnet sich mit der trivialen trigonometrie...
:roll:
x=zentrum.x+radius*cos(winkel)
y=zentrum.y+radius*sin(winkel)

den winkel soll dabei irgendwie von der zeit linear abhängen, also etwa

winkel=omega*t+phi, omega phi konstanten
 
G

Guest

Gast
Ich habe mal eine kleine Skizze gemacht. Die Linie soll ihre Länge natürlich nicht verändern. Ich möchte quasi die Koordinaten des Start- und Endpunktes einer Linie um ein Rotationszentrum rotieren lassen. Dabei liegt nie einer der Punkte im Rotationszentrum.


Und richtig, ich benutze nicht Graphics2D.
 

Marco13

Top Contributor
Schau mal hier
http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/AffineTransform.html#setToRotation(double,%20double,%20double)

Damit kannst du dann einzelne Punkte (oder ganze Arrays) transformieren
http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/AffineTransform.html#setToRotation(double,%20double,%20double)
 

0x7F800000

Top Contributor
http://de.wikipedia.org/wiki/Rotationsmatrix#Drehmatrix_der_Ebene_R.C2.B2
bei affinen transformationen fasst man zusätzlich 2D vektoren (x,y) zu 3-Tupeln (x,y,1) zusammen und transformiert die mit einer 3x3-Matrix, bei der in der dritten spalte zusätzlich die translation mit reingepackt ist... nur so, ein bisschen was zum hintergrund... schreib dir am besten schnell mal selbst eine klasse für die dreh und translationsmatrizen, das fördert das verständnis unheimlich...
 
G

Guest

Gast
Vielen Dank für eure Antworten!

Ich werde mich da mal reinarbeiten ... auch wenn es nicht "schnell mal selbst eine Klasse schreiben" wird. Eine gute Übung ist das sicherlich allemal.
 
G

Guest

Gast
Ui, das ist starker Tobak - bin kein Mathe- oder Informatiker. Habe doch erstmal die Klasse AffineTransform verwendet.

Das Rotieren um ein Rotationszentrum klappt schonmal wunderbar. Jetzt möchte ich aber noch eine rotierte Linie parallel verschieben. Und zwar entweder zum Rotationszentrum hin oder weg.

Doch dies klappt bisher genausowenig wie das auslesen der Koordianten des Start- und Endpunktes der rotierten Linie.

Würde mich über eure Hilfe sehr freuen!

Hier der aktuelle Code:

Code:
class MyPanel extends JPanel {
    
    public void MyPanel() {
        setBorder(BorderFactory.createLineBorder(Color.black));
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        
        // Setzen und Zeichnen der Ursprungslinie
        Line2D line = new Line2D.Double(100,100,100,150);
        g2d.draw(line);
        
        
        // Rotieren der Ursprungslinie um das Rotationszentrum (125,125)
        AffineTransform t = new AffineTransform();
        t.setToRotation(Math.toRadians(29), 125, 125);
        g2d.setTransform(t);
        g2d.setColor( Color.red );
        g2d.draw(line);
        
        // Ausgabe der Koordinaten der Linie
        System.out.println("=============================================================");
        System.out.println("Line: ("+line.getX1()+","+line.getY1()+" -> ("+line.getX2()+","+line.getY2()+")");
        System.out.println("=============================================================");
        
        // Parallelverschiebung der zweiten (roten) Linie ... klappt nicht
        t.setToTranslation(10, 10);
        g2d.setTransform(t);  
        g2d.setColor( Color.blue );
        g2d.draw(line);
    }
    
}
 

Marco13

Top Contributor
Es gibt auch Leute, die in ihrem Garten Gemüse anbauen und keine Gärtner sind. Wenn man so etwas machen will, ist AffineTransform schon ein ziemlich praktisches Werkzeug, da braucht man sowas wie Homogene Koordinaten und Pojektionen auf die 3dimensionale Hyperebene gernicht verstanden zu haben - aber um ein paar Basics wird man nicht drumrumkommen.

Im Moment bewegst du die Linie nicht. Sie wird nur "gedreht gezeichnet". Wenn du die Linie wirklich drehen willst, darfst du die AffineTransform nicht im Graphics2D setzen, sondern musst sie wirklich auf die Endpunkte der Linie anwenden (wie ich auch schon angedeutet hatte - der zweite Link sollte nämlich hierhin
http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/AffineTransform.html#transform(java.awt.geom.Point2D,%20java.awt.geom.Point2D)
verweisen... :roll: )

Code:
AffineTransform t = new AffineTransform();
t.setToRotation(Math.toRadians(29), 125, 125); 
t.transform(line.getPoint1(), line.getPoint1());
t.transform(line.getPoint2(), line.getPoint2());
System.out.println("Line: ("+line.getX1()+","+line.getY1()+" -> ("+line.getX2()+","+line.getY2()+")"); // Müßte dann die gedrehten Koordinaten ausgeben

In bezug auf das zusätzliche Verschieben: Man kann mehrere AffineTransforms miteinander multiplizieren, und das Produkt dieser AffineTransforms ist dann wieder eine AffineTransform, die die Hintereinanderausführung der einzelnen Bewegungen/Drehungen beschriebt.
Code:
AffineTransform t1 = new AffineTransform();
t1.setToRotation(Math.toRadians(29), 125, 125); 

AffineTransform t0 = new AffineTransform();
t0.setToTranslation(10,10);

AffineTransform tFinal = new AffineTransform(t0);
tFinal.concatenate(t1); // "Concatenate" heißt "verknüpfen", bzw. "miteinander multiplizieren"
tFinal.transform(line.getPoint2(), line.getPoint2()); // Bewirkt, dass der Punkt erst gedreht und dann verschoben wird
Beides ungetestet. Aber so in etwa.
 
G

Guest

Gast
Vielen Dankl für die Antwort!

Das mit dem Drehen klappt jetzt sehr gut. Allerdings ist das verschieben nicht ganz das, was ich möchte.

Wie in der nachfolgenden Skizze verdeutlicht, möchte ich eine Linie parallel zur gedrehten Linie verschieben. Aber so, dass der Mittelpunkt (orange Markierung) der ursprünglichen Linie und der verschobenen Linie auf einem Radius vom Rotationszentrum zum Liegen kommt. D.h., dass sich die verschobenene Linie nur innerhalb der hellgrün markierten Grenzen bewegen darf.

Das Verschieben sollte so funktionieren, dass die Radiuslänge (also der Abstand des Mittelpunktes der Linie vom Rotationszentrum) gesetzt werden kann und alles andere berechnet wird.

Sowas sollte doch möglich sein, oder? Irgendwelche Ideen oder Vorschläge? :)

Ich habe mich auch mal mit Geodreieck und Zirkel hingesetzt und ausprobiert. Das Rotieren des Start- und Endpunktes ist recht einfach mit den trigonomischen Funktiionen (sin, cos) zu bewerkstelligen. Hingegen habe ich für das Verschieben keine Lösung finden können.

145c7ab80236dde613509c7dc.png


Code:
@Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        
        // Zeichnen des Rotationszentrums
        Ellipse2D arc = new Ellipse2D.Double(200, 125, 2, 2);
        g2d.draw(arc);
        
        // Setzen und Zeichnen der Ursprungslinie
        Line2D line = new Line2D.Double(100,100,100,150);
        g2d.draw(line);
        System.out.println("=============================================================");
        System.out.println("Line 1: ("+line.getX1()+","+line.getY1()+" -> ("+line.getX2()+","+line.getY2()+")");
        
        // Rotieren der Ursprungslinie um das Rotationszentrum (125,125)
        AffineTransform t0 = new AffineTransform();
        Point2D p1 = new Point2D.Double();
        Point2D p2 = new Point2D.Double();
        t0.setToRotation(Math.toRadians(45), 200, 125);
        t0.transform(line.getP1(), p1);
        t0.transform(line.getP2(), p2);
        line.setLine(p1, p2);
        
        System.out.println("Line 2: ("+line.getX1()+","+line.getY1()+" -> ("+line.getX2()+","+line.getY2()+")");
        g2d.setColor( Color.red );
        g2d.draw(line);
        
        // Parallelverschiebung der zweiten (roten) Linie ... klappt nicht
        AffineTransform t1 = new AffineTransform();
        t1.setToRotation(Math.toRadians(29), 125, 125);
        
        AffineTransform t2 = new AffineTransform();
        t2.setToTranslation(30,3T0); 
        
        AffineTransform tf = new AffineTransform(t1); 
        tf.concatenate(t2);
        
        tf.transform(line.getP1(), p1);
        tf.transform(line.getP2(), p2);
        line.setLine(p1, p2);
        
        System.out.println("Line 3: ("+line.getX1()+","+line.getY1()+" -> ("+line.getX2()+","+line.getY2()+")");
        System.out.println("=============================================================");
        g2d.setColor( Color.blue );
        g2d.draw(line);
    }
 

Marco13

Top Contributor
Schwarz, rot, magenta, blau - welche der Linien ist die original-Linie, welche die gedrehte, welche die verschobene? Auf welcher Linie soll die Verschiebung stattfinden?
 
G

Guest

Gast
Die schwarze Linie ist die Ursprungslinie. Diese wurde um das Rotationszentrum (der kleine unscheinbare Punkt am linken unteren Ende der grünen Straße) gedreht und kommt als orange Linie zum Erliegen. Diese orange Linie ist okay (Rotation um 45 Grad).

Den Mittelpunkt der Linien habe ich mit einen orangen Punkt markiert.

Wenn man jetzt einen Radius, ausgehend vom Rotationszentrum, durch den Mittelpunkt der orangen Linie zeichnet, dann sollte es möglich sein, diese orange Linie auf dem Radius parallel zu verschieben. Entweder zum Rotationszentrum hin oder davon weg. Die rosa Linie wäre ein mögliches richtiges Resultat. In diesem Beispiel sollten es also nur Parallelverschiebungen der orangen Linie innerhalb der grünen Straße möglich sein.

Die blaue Linie hingegen ist das aktuelle Resulat. Die ist zwar innerhalb der grünen Straße, aber nicht parallel zur orangen Linie.

Das ferne Ziel ist es, dass ich per Klick mit der linken Maustaste die Linie setzen (das Rotationszentrum wird automatisch mit generiert), die Linie mit dem Mausrad um das Rotationszentrum drehen und mit zwei Keyboard-Tasten die Linie auf das Rotationszentrum zu und fort bewegen kann.
Naja, eigentlich werden es zwei Linien sein, die sich auf entgegengesetzten Seiten des Roationszentrums befinden werden.
 
G

Guest

Gast
Es funktioniert!

Ich habe das jetzt so gemacht, dass ich, wenn der Radius verändert wurde, die Linie komplett neu rotieren lasse. Somit brauche ich nicht die rotierte Linie zum Rotationszentrum hin oder davon fort bewegen.

Allerdings habe ich zwei neue Probleme. ;-)

1)
Wenn ich die Linien mit
Code:
AffineTransform t = new AffineTransform();
t.setToRotation(Math.toRadians(angle), center.getX(), center.getY());
g2d.setTransform(t);
um das Rotationszentrum "Point2D center" rotieren lasse, dann werden offensichtlich die Dimensionen von JFrame und nicht JPanel zugrunde gelegt. In JPanel wird aber gezeichnet und JFrame hat damit nichts zu tun. Wie mache ich AffineTransform klar, dass er sich nur auf JPanel beziehen soll? Denn augenblicklich verzieht sich beim Rotieren alles nach oben (JFrame ist deutlich höher als JPanel).

2)
Ich habe eine Klasse "MyPanel" von JPanel abgeleitet und dort die Methode "paintComponent" überschrieben.
Code:
@Override
    public void paintComponent(Graphics g) {
        myLeftLine.paintLine(g, 0);        
        myRightLine.paintLine(g, 1);        
    }
Jetzt ist es so, dass diese Methode scheinbar "andauernd" aufgerufen wird. Auch ohne, dass ich Eigenschaften der Instanz der Klasse MyPanel veränder oder die Methode repaint() aufrufe.

Auf jeden Fall wird zeilenweise "check -> 1" und "check -> 2" in der Konsole gedruckt.

Woran liegt das?
Code:
class MyLine {
[...]

public void paintLine(Graphics g, int color) {
        if(x != 0 && y != 0) {
            
            Graphics2D g2d = (Graphics2D)g;
            AffineTransform t = new AffineTransform();
            
//            Point2D p0 = new Point2D.Double(x, y);
            Point2D p1 = new Point2D.Double(x, y + (LENGTH / 2));
            Point2D p2 = new Point2D.Double(x, y - (LENGTH / 2));
                    
            switch(color) {
                case 0: g2d.setColor(Color.ORANGE); break;
                case 1: g2d.setColor(Color.RED); break;
            }
            
            Line2D line = new Line2D.Double(p1, p2);
            System.out.println("check -> 1");
            
            if(angle != 0) {
                t.setToRotation(Math.toRadians(angle), center.getX(), center.getY());
                g2d.setTransform(t);
                System.out.println("check -> 2");
            }
            
            // Zeichnen der Linie
            g2d.draw(line);
            
            // Zeichnen des Rotationszentrums
            Ellipse2D dot = new Ellipse2D.Double(center.getX(), center.getY(), 2, 2);
            g2d.draw(dot);
        }
    }
}
 

Marco13

Top Contributor
Hm. Zum 1: Wenn du dir das Rotationszentrum anzeigen läßt, sollte man eigentlich erkennen, worum genau rotiert wird. (D.h. mir ist nicht klar, wie es sich äußert, dass "die Dimensionen des JFrame zugrunde gelegt" werden).

Es kann (anfangs) SEHR verwirrend aussehen, wenn man Verschiebungen und Drehungen kombiniert. Es ist ja z.B. ein gewaltiger Unterschied, ob men ERST dreht und DANN verschiebt, oder umgekehrt....

2. Und wenn paintComponent immer wieder aufgerufen wird... Schau' mal, ob du irgendwo im Bereich der paintComponent-Methode ein "repaint()" aufrufst. Oder hast du irgendwo einen Thread, der irgendwelche Swing-Komponenten verändert oder so?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Punkt von MouseListener hat falsche Koordinate AWT, Swing, JavaFX & SWT 2
P Abwächselnd ein Punkt und ein x anzeigen AWT, Swing, JavaFX & SWT 2
L 2D-Grafik Frage zu Ellipse2D.Double, Abfrage, ob Punkt enthalten ist funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Rectangle g.fillRec() X/Y Punkt AWT, Swing, JavaFX & SWT 5
S Punkt finden der in einem Shape liegt..? AWT, Swing, JavaFX & SWT 11
K 2D-Grafik Punkt in Eclipse AWT, Swing, JavaFX & SWT 4
S Bild von Punkt zu Punkt zeichnen AWT, Swing, JavaFX & SWT 8
B 3D-Grafik Punkt in JAVA3D darstellen AWT, Swing, JavaFX & SWT 2
L Swing struktur und nahester Punkt AWT, Swing, JavaFX & SWT 4
J Punkt-genaue Positionierung von SWT-Komponenten AWT, Swing, JavaFX & SWT 10
T JComboBox Komma in Punkt umwandeln AWT, Swing, JavaFX & SWT 2
S JTable Float Column fuegt automatisch Punkt hinzu wenn man Zahlen eingibt. AWT, Swing, JavaFX & SWT 21
X Punkt auf Geometrie AWT, Swing, JavaFX & SWT 24
G Blinkenden Punkt zeichen AWT, Swing, JavaFX & SWT 2
S Will einen Punkt zeichnen aber krieg das net hin. AWT, Swing, JavaFX & SWT 2
J JScrollPane soll automatisch zu einem punkt scrollen AWT, Swing, JavaFX & SWT 4
S FAQ und JTable Tutorial.Teil.4 Punkt 5 wichtige Bemerkung AWT, Swing, JavaFX & SWT 2
T drehung um einen anderen punkt AWT, Swing, JavaFX & SWT 2
R Hässlicher Punkt bei JPopupMenu AWT, Swing, JavaFX & SWT 12
E x wert von einem vorhandenen punkt abziehen? AWT, Swing, JavaFX & SWT 3
U Wie funktioniert das rotieren unter 2dGraphics, also wie stelle ich z. B. 90° ein? AWT, Swing, JavaFX & SWT 1
M JavaFX rotieren eines Kreises mit konstanter Geschwindigkeit AWT, Swing, JavaFX & SWT 1
J JavaFX ImageView rotieren lassen AWT, Swing, JavaFX & SWT 1
S JPanel rotieren, Bild ist abgeschnitten, Clipping? AWT, Swing, JavaFX & SWT 0
S 2D-Grafik User-BufferedImage rotieren im Zentrum und ohne "anpassung" AWT, Swing, JavaFX & SWT 2
M [JavaFX] Objekt um Zentrum rotieren (Camera) AWT, Swing, JavaFX & SWT 1
R TriangleMesh verschwindet teilweise beim resizen des Frames, sowie beim rotieren? AWT, Swing, JavaFX & SWT 1
U Image mit Zeichenbereich rotieren AWT, Swing, JavaFX & SWT 3
P Label rotieren mit Timer AWT, Swing, JavaFX & SWT 5
T 2D-Grafik Rotieren von Bildern AWT, Swing, JavaFX & SWT 3
S einzelnd Rotieren AWT, Swing, JavaFX & SWT 5
Luk10 2D-Grafik BufferedImage sauber rotieren AWT, Swing, JavaFX & SWT 16
G Text rotieren: Frage zu einem Beispiel AWT, Swing, JavaFX & SWT 5
S swing komponenten mit mouselistener rotieren AWT, Swing, JavaFX & SWT 15
R JSpinner rotieren AWT, Swing, JavaFX & SWT 6
redztripe Graphics2D rotieren und rotiertes Bild abspeichern AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben