Dreieck um den Mittelpunkt rotieren lassen

Status
Nicht offen für weitere Antworten.

Deception

Mitglied
Hey Leute,
Ich habe ein Dreieck in einem Polygon! Das Dreieck ist gleichschenklig, daher hat es eine Spitze C, deren Punkte A und B gleich weit voneinander entfernt sind. Nun möchte ich das Dreieck nach Links oder Rechts drehen lassen.
Das ganze ist nun vielleicht eine eher mathematische Frage: Wie berechne ich die Koordinaten für A' B' und C'?
Ich habe mich heute schon den ganzen Tag damit beschäftigt und etwas von AffineTransformation gelesen! Kann man das auch irgendwie auf ein Polygon anwenden? Wie erstelle ich diese AT Matrix, irgendwie hab ich damit leichte denk Probleme! ):
Code hab ich jetzt direkt noch keinen zur Verfügung, da ich mir erstmal über das WIE Gedanken mache... Hoffe mir kann trotzdem jmd. das ganze erklären und Code Beispiel wäre natürlich noch am aller besten :)
Vielen Dank,
Jens
 

Marco13

Top Contributor
Polygon ist ein bißchen "unpraktisch", um es zu rotieren, aber mit einer AffineTransform geht es einigermaßen. Du würdest dann erst den Mittelpunkt ausrechnen
Code:
double x = (polygon.xpoints[0] + polygon.xpoints[1] + polygon.xpoints[2])/3.0;
double y = (polygon.ypoints[0] + polygon.ypoints[1] + polygon.ypoints[2])/3.0;
dann eine passende AffineTransform erstellen, die um den Mittelpunkt rotiert
Code:
AffineTransform at = new AffineTransform();
at.setToRotation(Math.toRadians(45), x,y);
und die dann (das ist jetzt das "unpraktische") auf das Polygon anwenden
Code:
for (int i=0; i<polygon.npoints; i++)
{
    Point2D.Double p = new Point2D.Double(polygon.xpoints[i], polygon.ypoints[i]);
    at.transform(p);
    polygon.xpoints[i] = (int)p.x;
    polygon.ypoints[i] = (int)p.y;
}

Wenn du das Polygon aber "häufiger" rotieren willst, solltest du das Original speichern, und immer nur eine Kopie mit den Daten des gedrehten Polygons füllen - sonst entstehen (durch das casten nach int) riesige Rundungsfehler.
 

Deception

Mitglied
Vielen Dank schonmal! Also das Dreieck rotiert, das gefällt mir schonmal ;)
Aber es bewegt sich gleichzeitig in eine richtung nach oben rechts? Woran liegt das? :/
Ich hab den Code von dir einfach mal übernommen bzw. ihn ein wenig für mich angepasst:

Code:
public void rotate()
	{
		Polygon polygon = new Polygon();
		polygon.addPoint((int)xkoordSpitze, (int)ykoordSpitze);
		polygon.addPoint((int)xkoordLinks, (int)ykoordLinks);
		polygon.addPoint((int)xkoordRechts, (int)ykoordRechts);
		

		double x = (polygon.xpoints[0] + polygon.xpoints[1] + polygon.xpoints[2])/3.0;
		double y = (polygon.ypoints[0] + polygon.ypoints[1] + polygon.ypoints[2])/3.0;
		
		AffineTransform at = new AffineTransform();
		at.setToRotation(Math.toRadians(winkel), x,y);
		
		for (int i=0; i<polygon.npoints; i++)	
		{
		    Point2D.Double p = new Point2D.Double(polygon.xpoints[i], polygon.ypoints[i]);
		    at.transform(p,p);
		    polygon.xpoints[i] = (int)p.x;
		    polygon.ypoints[i] = (int)p.y;
		}
		xkoordSpitze = polygon.xpoints[0];
		xkoordLinks = polygon.xpoints[1];
		xkoordRechts = polygon.xpoints[2];
		
		ykoordSpitze = polygon.ypoints[0];
		ykoordLinks = polygon.ypoints[1];
		ykoordRechts = polygon.ypoints[2];
	}
 

Deception

Mitglied
Hey,
ist aber nichts schönes, sehr umständlich zum Teil, da es nur zum Ausprobieren war, für nen Spiel ;)

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;

import javax.swing.JPanel;

public class MyPanel extends JPanel
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Dreieck d;
	
	public MyPanel()
	{
		super();
		d = new Dreieck(this);
		d.start();
	}
	
	public void paint(Graphics g)
	{
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, 500, 500);
		if(d != null)
		{
			double[] xkoords = d.getXkoords();
			double[] ykoords = d.getYkoords();
			Polygon polygonen = new Polygon();
			
			polygonen.addPoint((int)xkoords[0], (int)ykoords[0]);
			polygonen.addPoint((int)xkoords[1], (int)ykoords[1]);
			polygonen.addPoint((int)xkoords[2], (int)ykoords[2]);
			
			g.setColor(Color.RED);
			g.fillPolygon(polygonen);
		}
	}
}

import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

public class Dreieck extends Thread
{
	private double winkel= 90;
	private double xkoordSpitze;
	private double xkoordLinks;
	private double xkoordRechts;
	private double ykoordSpitze;
	
	private double ykoordLinks;
	private double ykoordRechts;
	private int speed = 0;
	
	private MyPanel panel;
	
	public Dreieck(MyPanel panel)
	{
		this.panel = panel;
		xkoordSpitze = 65;
		xkoordLinks = 45;
		xkoordRechts = 85;
		
		ykoordSpitze = 50;
		ykoordLinks = 70;
		ykoordRechts = 70;
	}
	
	/**
	 * Gibt die x-Koordinate des Schiffes zurueck
	 * 
	 * @return xkoord double
	 */
	public double[] getXkoords()
	{
		double[] xkoords = new double[3];
		xkoords[0] = xkoordSpitze;
		xkoords[1] = xkoordLinks;
		xkoords[2] = xkoordRechts;
		return xkoords;
	}
	/**
	 * Gibt die y-Koordinate des Schiffes zurueck
	 * 
	 * @return ykoord double
	 */
	public double[] getYkoords()
	{
		double[] ykoords = new double[3];
		ykoords[0] = ykoordSpitze;
		ykoords[1] = ykoordLinks;
		ykoords[2] = ykoordRechts;
		return ykoords;
	}
	
	public void turnLeft()
	{
		winkel -= 5;
		rotate();
		panel.repaint();
	}
	public void rotate()
	{
		Polygon polygon = new Polygon();
		polygon.addPoint((int)xkoordSpitze, (int)ykoordSpitze);
		polygon.addPoint((int)xkoordLinks, (int)ykoordLinks);
		polygon.addPoint((int)xkoordRechts, (int)ykoordRechts);
		

		double x = (polygon.xpoints[0] + polygon.xpoints[1] + polygon.xpoints[2])/3.0;
		double y = (polygon.ypoints[0] + polygon.ypoints[1] + polygon.ypoints[2])/3.0;
		
		AffineTransform at = new AffineTransform();
		at.setToRotation(Math.toRadians(winkel), x,y);
		
		for (int i=0; i<polygon.npoints; i++)	
		{
		    Point2D.Double p = new Point2D.Double(polygon.xpoints[i], polygon.ypoints[i]);
		    at.transform(p,p);
		    polygon.xpoints[i] = (int)p.x;
		    polygon.ypoints[i] = (int)p.y;
		}
		xkoordSpitze = polygon.xpoints[0];
		xkoordLinks = polygon.xpoints[1];
		xkoordRechts = polygon.xpoints[2];
		
		ykoordSpitze = polygon.ypoints[0];
		ykoordLinks = polygon.ypoints[1];
		ykoordRechts = polygon.ypoints[2];
	}

	public void turnRight()
	{
		winkel += 5;
		rotate();
		panel.repaint();
	}
	
	public void erhoeheSpeed()
	{
		speed += 1;
	}
	
	public void run()
	{
		try
		{
			Thread.sleep(2000);
			for(int i = 0; i < 20; i++)
			{
				turnRight();
				Thread.sleep(200);
			}
			Thread.sleep(3000);
			for(int j = 0; j < 20; j++)
			{
				turnLeft();
				Thread.sleep(200);
			}
		}
		catch(InterruptedException ie)
		{
			
		}
	}
}
import javax.swing.JFrame;

public class MyFrame
{
	public static void main(String[] args)
	{
		JFrame frame = new JFrame("Rotation eines Dreiecks");
		MyPanel panel = new MyPanel();
		frame.getContentPane().add(panel);
		frame.setSize(200,200);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

Sry ;)
 

Quickbeam2k1

Aktives Mitglied
Also ich als mathematiker würde da mal folgendes sagen:

Ich nehme mal an wir sind im R^2, also in der Ebene.

Das heisst die Eckpunkte meines Dreiecks sind jeweils ein Vektor (x_1,x_2).

Nun definiere ich eine Euklidische Bewegung.

f(x)=A*x+b
Hierbei ist x ein Vektor sowas wie (1,2).
b ist dann der Vektor der für die affine Transformation zuständig ist. Der Verschiebt dir also alle deine Punkte entsprechend.

Die Matrix A ist nun die Matrix die für die Drehung zuständig ist.

Hier nimmt man auch direkt eine sogenannte Drehmatrix der Form:

( cos alpha, sin alpha \\ <<- neue Zeile
-sin alpha, cos alpha)

Wobei alpha halt aus 0 bis 2pi ist.

Diese Abbildugn wenndest du nun auf deine 3 Eckpunkte an. Diese werden also transformiert, so dass du dir nur merken musst welche Punkte du nun miteinander verbinden möchtest.

Also gar keinen Umweg über den Schwerpunkt des Dreiecks ;)
 

Marco13

Top Contributor
Marco13 hat gesagt.:
Wenn du das Polygon aber "häufiger" rotieren willst, solltest du das Original speichern, und immer nur eine Kopie mit den Daten des gedrehten Polygons füllen - sonst entstehen (durch das casten nach int) riesige Rundungsfehler.

Das war nicht nur so dahin gesagt :roll: Dein Dreieck verschiebt sich nicht nur, sondern es verformt sich auch. Früher oder später würde es zu einem Punkt (bei 0,0) zusammenschnurren, weil bei jedem casten nach 'int' wichtige Nachkommastellen weggeschnitten werden.

Also: Du mußt einmal dein Original-Dreieck speichern, und dann immer nur die gedrehte Kopie anzeigen. Abgesehen davon, dass du das Dreieck "immer schneller" gedreht hast: Erst um 5 grad, dann um 10 Grad, dann um 15 Grad - das macht NUR Sinn, wenn man immer vom gleichen (ungedrehten) Dreieck ausgeht.

Du solltest dein Dreieck (und jede kompliziertere Objekt) vielleicht etwas "eleganter" speichern - das mit dem "xKoordSpitze" und "yKoordLinks" usw. ist ziemlich unhandlich. Aber ich habe das Programm mal im gleichen Stil (!) sinngemäß abgeändert. Die Relevanten Teile sind mit ========== markiert.

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import javax.swing.*;

public class MyFrame
{
   public static void main(String[] args)
   {
      JFrame frame = new JFrame("Rotation eines Dreiecks");
      MyPanel panel = new MyPanel();
      frame.getContentPane().add(panel);
      frame.setSize(200,200);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
}

class MyPanel extends JPanel
{
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private Dreieck d;

   public MyPanel()
   {
      super();
      d = new Dreieck(this);
      d.start();
   }

   public void paint(Graphics g)
   {
      g.setColor(Color.BLACK);
      g.fillRect(0, 0, 500, 500);
      if(d != null)
      {
         double[] xkoords = d.getXkoords();
         double[] ykoords = d.getYkoords();
         Polygon polygonen = new Polygon();

         polygonen.addPoint((int)xkoords[0], (int)ykoords[0]);
         polygonen.addPoint((int)xkoords[1], (int)ykoords[1]);
         polygonen.addPoint((int)xkoords[2], (int)ykoords[2]);

         g.setColor(Color.RED);
         g.fillPolygon(polygonen);
      }
   }
}

class Dreieck extends Thread
{
   private double winkel= 90;
   private double xkoordSpitze;
   private double xkoordLinks;
   private double xkoordRechts;
   private double ykoordSpitze;
   private double ykoordLinks;
   private double ykoordRechts;


   //========================================= Original-Koordinaten
   private double xkoordSpitzeOrig;
   private double xkoordLinksOrig;
   private double xkoordRechtsOrig;
   private double ykoordSpitzeOrig;
   private double ykoordLinksOrig;
   private double ykoordRechtsOrig;


   private int speed = 0;

   private MyPanel panel;


   public Dreieck(MyPanel panel)
   {
      this.panel = panel;

      //========================================= Original-Koordinaten bekommen Werte
      xkoordSpitzeOrig = 65;
      xkoordLinksOrig = 45;
      xkoordRechtsOrig = 85;

      ykoordSpitzeOrig = 50;
      ykoordLinksOrig = 70;
      ykoordRechtsOrig = 70;

      xkoordSpitze = xkoordSpitzeOrig;
      xkoordLinks = xkoordLinksOrig;
      xkoordRechts = xkoordRechtsOrig;

      ykoordSpitze = ykoordSpitzeOrig;
      ykoordLinks = ykoordLinksOrig;
      ykoordRechts = ykoordRechtsOrig;
   }

   /**
    * Gibt die x-Koordinate des Schiffes zurueck
    *
    * @return xkoord double
    */
   public double[] getXkoords()
   {
      double[] xkoords = new double[3];
      xkoords[0] = xkoordSpitze;
      xkoords[1] = xkoordLinks;
      xkoords[2] = xkoordRechts;
      return xkoords;
   }
   /**
    * Gibt die y-Koordinate des Schiffes zurueck
    *
    * @return ykoord double
    */
   public double[] getYkoords()
   {
      double[] ykoords = new double[3];
      ykoords[0] = ykoordSpitze;
      ykoords[1] = ykoordLinks;
      ykoords[2] = ykoordRechts;
      return ykoords;
   }

   public void turnLeft()
   {
      winkel -= 5;
      rotate();
      panel.repaint();
   }
   public void rotate()
   {
      //========================================= Polygon auf Basis der Original-Koordinaten erstellen 
      Polygon polygon = new Polygon();
      polygon.addPoint((int)xkoordSpitzeOrig, (int)ykoordSpitzeOrig);
      polygon.addPoint((int)xkoordLinksOrig, (int)ykoordLinksOrig);
      polygon.addPoint((int)xkoordRechtsOrig, (int)ykoordRechtsOrig);


      double x = (polygon.xpoints[0] + polygon.xpoints[1] + polygon.xpoints[2])/3.0;
      double y = (polygon.ypoints[0] + polygon.ypoints[1] + polygon.ypoints[2])/3.0;

      AffineTransform at = new AffineTransform();
      at.setToRotation(Math.toRadians(winkel), x,y);

      for (int i=0; i<polygon.npoints; i++)
      {
          Point2D.Double p = new Point2D.Double(polygon.xpoints[i], polygon.ypoints[i]);
          at.transform(p,p);
          polygon.xpoints[i] = (int)p.x;
          polygon.ypoints[i] = (int)p.y;
      }

      //========== Das, was gezeichnet wird, sind nach wie vor die xkoordSpitze usw. 
      // Die Original-Koordinaten werden immer nur verwendet, um am Anfang das un-gedrehte Polygon zu erstellen

      xkoordSpitze = polygon.xpoints[0];
      xkoordLinks = polygon.xpoints[1];
      xkoordRechts = polygon.xpoints[2];

      ykoordSpitze = polygon.ypoints[0];
      ykoordLinks = polygon.ypoints[1];
      ykoordRechts = polygon.ypoints[2];
   }

   public void turnRight()
   {
      winkel += 5;
      rotate();
      panel.repaint();
   }

   public void erhoeheSpeed()
   {
      speed += 1;
   }

   public void run()
   {
      try
      {
         Thread.sleep(2000);
         for(int i = 0; i < 20; i++)
         {
            turnRight();
            Thread.sleep(200);
         }
         Thread.sleep(3000);
         for(int j = 0; j < 20; j++)
         {
            turnLeft();
            Thread.sleep(200);
         }
      }
      catch(InterruptedException ie)
      {

      }
   }
}
 

Marco13

Top Contributor
@Quickbeam2k1: Wenn man UM den Mittelpunkt rotieren will, bleibt einem fast nichts anderes übrig, als den Mittelpunkt zu bestimmen. Und wenn man dann (wie die AffineTransform-Klasse) so spendabel ist, und für eine Transformation im 2D eine 3x3-Matrix zu verwenden, kann man praktischerweise auch eine Verschiebung (die ja eigentlich affin ist) als Lineare Abbildung beschreiben (weil man dann implizit mit homogenen Koordinaten rechnet, und eine affine Abbildung im im n-dimensionalen (in diesem Fall, aber ich glaube, auch ganz allgemein) durch eine Lineare Abbildung im n+1-dimensionalen beschrieben werden kann)
 

Quickbeam2k1

Aktives Mitglied
@ marco du hast vollkommen recht ;)
Bei meinem Beispiel dreht man ja nur um den nullpunkt ;)

ich verkrich mich mal wieder in mein loch
 

Deception

Mitglied
Hey,
Vielen Dank ihr 2 :)
Also das mit den Koordinaten, wie gesagt, es ist nur zum Testen. In meinem Original Spiel wird es natürlich alles viel schöner gemacht ;) Auch das casten hab ich der Einfachheit wegen zum Testen weggelassen, weil ich einfach schauen wollte wies so funktioniert ;)
Sooo ich teste das dann bald mal durch.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Quadrat Textur lädt als Dreieck Spiele- und Multimedia-Programmierung 3
S Dreieck zeichnen Spiele- und Multimedia-Programmierung 9
T [jogl] ein einfaches Dreieck darstellen Spiele- und Multimedia-Programmierung 3
E [LWJGL] Karusell, mehrere Objekte drehen sich um einen Mittelpunkt Spiele- und Multimedia-Programmierung 31
B MarioKart Map rotieren? Spiele- und Multimedia-Programmierung 6
D 2D Pixelbild rotieren Spiele- und Multimedia-Programmierung 3
TulPe Würfel per Mausklick rotieren Spiele- und Multimedia-Programmierung 10
Creylon [LWJGL] 2D Sprite Rotieren/Drehen Spiele- und Multimedia-Programmierung 6
B j3d mehr als ein Objekt rotieren Spiele- und Multimedia-Programmierung 18
G Rotieren eines Objekts (2D) Spiele- und Multimedia-Programmierung 8
M [Java3D] Rotieren der Scene NICHT des POV Spiele- und Multimedia-Programmierung 4
Developer_X 3D Point rotieren lassen Spiele- und Multimedia-Programmierung 17
J Rotieren eines 2D Images endet in Java heap space Error Spiele- und Multimedia-Programmierung 15
W Affine Transformation, Rotieren eines Objekts Spiele- und Multimedia-Programmierung 2
S Schiff in Richtung der Maus rotieren - Problem :/ Spiele- und Multimedia-Programmierung 5
Tr3kk3r Kamera nur um x und y, nicht um z achse rotieren Spiele- und Multimedia-Programmierung 2
P Rechteck rotieren und frontal anzeigen Spiele- und Multimedia-Programmierung 2
A Objekte nacheinander zeitgesteuert rotieren lassen Spiele- und Multimedia-Programmierung 4

Ähnliche Java Themen


Oben