Polygonsize durch das umliegende Reckteck verändern inJava2D

Status
Nicht offen für weitere Antworten.
D

Diablo68

Gast
Hallo,

erstmal sorry an die Homepage Admins, dass ich den gleichen Inhalt zum zweiten Mal poste. Leider war es beim ersten Versuch in der falschen Rubrik gelandet, auf die ich wahrscheinlich deswegen kein Feedback bekommen habe.


Ich habe ein Tool geschrieben, mit der man mit Hilfe der Maus Polygone erstellen und in einem Vector abspeichern kann. Wenn man auf das jeweilige Polygon klickt, erscheint ein Reckteck um das Polygon herum. Ich möchte, dass sich das Polygon an die Rechteckgröße anpasst, wenn ich es vertikal, horizontal oder auch diagonal ändere. Das Rechteck kann man schon mit der Maus in beliebiger Richtung ändern, nur das Polygon bleibt statisch.

Wie kann ich vorgehen ?

Gruss

Diablo
 

Evil-Devil

Top Contributor
Wir wär's wenn du einfach ausrechnest um wieviel sich die Größe des Rechteckes verändert hat und diese Änderung entsprechend auf dein Polygon überträgst?
 
D

diablo68

Gast
Hi Evil,

danke für den Feedback..

Mit dem u.a Code funktioniert es :

Code:
// Linke Seite tranformieren
else if (aendereMinX && e.isMetaDown() == false) {	
int abs = zF.polyRect.x - (last_x + e.getX());
				
				zF.polyRect.setRect(last_x + e.getX(), zF.polyRect.y, 
						zF.polyRect.width + abs, zF.polyRect.height);
								
				for (int i = 0; i < p.npoints; i++) {
					int x = p.xpoints[i];
					boundsMaxX = Math.max(boundsMaxX, x);
					if (p.xpoints[i] < boundsMaxX) {
						p.xpoints[i] -= abs;
					}
				}
			}
 
G

Guest

Gast
diablo68 hat gesagt.:
Hi Evil,

danke für den Feedback..

Mit dem u.a Code funktioniert es nur teilweise:

Code:
// Linke Seite tranformieren
else if (aendereMinX && e.isMetaDown() == false) {	
   
   // Das Stück, das beim Tranfsformieren des Recktsecks dazugekommen ist.
   int abs = zF.polyRect.x - (last_x + e.getX());
  
   // Neue Werte werden dem Rechteck zugewiesen				
   zF.polyRect.setRect(last_x + e.getX(), zF.polyRect.y, 
		zF.polyRect.width + abs, zF.polyRect.height);

   // Polygon X-Punkt-Werte um abs erweitert/reduziert								
   for (int i = 0; i < p.npoints; i++) {
      int x = p.xpoints[i];
      boundsMaxX = Math.max(boundsMaxX, x);
      if (p.xpoints[i] < boundsMaxX) {
         p.xpoints[i] -= abs;
      }
   }
}

Die Punkte werden zwar um den neuen Rechtecksabstand erweitert, d.h werden parallel zur Rechtecksänderungen verschoben. Das Polygon wird aber nicht an allen Punkten skaliert. Nur zwischen boundsMaxX und seinen direkt verbundenen Punkten.

Wie kann ich den Code umschreiben, das alle Punkte proportional zum Reckteck skaliert werden ?

Gruß

Diablo
 

Marco13

Top Contributor
Wie Evil-Devil es schon angedeutet hat.

Code:
Rectanlge oldRect = Rechteck VOR der Größenänderung
Rectanlge newRect = Rechteck NACH der Größenänderung

for (alle Punkte p des Polygons)
{
    float relX = (float)(p.x - oldRect.x) / oldRect.width;
    float relY = (float)(p.y - oldRect.y) / oldRect.height;

    p.x = (int)(newRect.x + relX * newRect.width);
    p.y = (int)(newRect.y + relY * newRect.height);
}

EDIT: Ginge auch effizienter, aber so ist es vmlt. nachvollziehbarer...
 
G

Guest

Gast
Hallo nochmals,

also habe mein Code habe ich folgendermaßen geändert :

Code:
// Linke Seite tranformieren
else if (aendereMinX && e.isMetaDown() == false) {	
			
  int abs = zF.polyRect.x - (last_x + e.getX());
				
  zF.polyRect.setRect(last_x + e.getX(), zF.polyRect.y, 
	zF.polyRect.width + abs, zF.polyRect.height);
				
   for (int i = 0; i < p.npoints; i++) {
	float relX = (float)(p.xpoints[i] - old.x) / old.width;			    
	p.xpoints[i] = (int)((zF.polyRect.x + relX * zF.polyRect.width));
   } 
}

Also, das mit dem Skalieren des Polygons funktioniert wunderbar, aber es passt sich nicht an das Rechteck an.
Skaliert sehr schnell, dass er nicht mehr auf dem Monitor zusehen ist. Scheint an dem Skalierungswert zulegen.

Wo kann ich es ändern ?

Gruss

Celal
 

Marco13

Top Contributor
Lass mich raten: Das ganze "schnurrt" irgendwie zusammen, wenn man die Maus bewegt!? Vermutlich gibt es noch ein Problem, weil ja immer auf int zurückgecastet werden muss - es gehen dabei während der Mausbewegung ständig Informationen verloren. Du solltest evtl. das ursprüngliche Polygon speichern, und immer auf den gleichen Anfangsdaten rechnen (bis MouseReleased kommt). Hab' da gerade mal was zum Testen hingehackt:
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class PolygonPanel extends JPanel implements MouseListener, MouseMotionListener
{
    private Polygon polygon;
    private Rectangle rectangle;

    private Polygon editingPolygon;
    private Rectangle editingRectangle;

    public PolygonPanel()
    {
        int xpoints[] = new int[] { 200, 300, 200, 200, 100 };
        int ypoints[] = new int[] { 300, 200, 100, 200, 200 };
        polygon = new Polygon(xpoints, ypoints, xpoints.length);

        rectangle = new Rectangle(100,100,200,200);

        addMouseListener(this);
        addMouseMotionListener(this);
    }

    public void paintComponent(Graphics gr)
    {
        Graphics2D g = (Graphics2D)gr;

        g.setColor(Color.WHITE);
        g.fillRect(0,0,getWidth(),getHeight());


        g.setColor(Color.BLACK);
        g.fill(polygon);
        g.draw(rectangle);

        g.setColor(Color.RED);
        if (editingRectangle != null) g.draw(editingRectangle);
        if (editingPolygon != null) g.draw(editingPolygon);

    }

    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e)
    {
        // Neues Polygon für die Dauer des Editierens erstellen
        int xp[] = polygon.xpoints.clone();
        int yp[] = polygon.ypoints.clone();
        editingPolygon = new Polygon(xp, yp, polygon.xpoints.length);
        editingRectangle = (Rectangle)rectangle.clone();
        repaint();
    }

    public void mouseReleased(MouseEvent e)
    {
        // Daten aus dem editier-Polygon in das "richtige" Polygon kopieren
        // (hack: Eigentlich nicht klonen, sondern einfach rüberkopieren!)
        int xp[] = editingPolygon.xpoints.clone();
        int yp[] = editingPolygon.ypoints.clone();
        polygon = new Polygon(xp, yp, editingPolygon.xpoints.length);
        rectangle = (Rectangle)editingRectangle.clone();
        editingPolygon = null;
        editingRectangle = null;
        repaint();
    }
    public void mouseClicked(MouseEvent e){}

    public void mouseMoved(MouseEvent e){}
    public void mouseDragged(MouseEvent e)
    {
        Rectangle oldRect = rectangle;
        Rectangle newRect = editingRectangle;
        editingRectangle.width = e.getX() - editingRectangle.x;
        editingRectangle.height = e.getY() - editingRectangle.y;

        // Berechne die Koordinaten des NEUEN Polygons auf
        // Basis der Informationen aus dem ALTEN Polygon
        // und des alten+neuen Rectangles
        for (int i=0; i<editingPolygon.xpoints.length; i++)
        {
            Point p = new Point(polygon.xpoints[i], polygon.ypoints[i]);

            float relX = (float)(p.x - oldRect.x) / oldRect.width;
            float relY = (float)(p.y - oldRect.y) / oldRect.height;

            p.x = (int)(newRect.x + relX * newRect.width);
            p.y = (int)(newRect.y + relY * newRect.height);

            editingPolygon.xpoints[i] = p.x;
            editingPolygon.ypoints[i] = p.y;
        }
        repaint();
    }
}


class RectangleTest extends JFrame
{
    public static void main(String args[])
    {
        new RectangleTest();
    }

    public RectangleTest()
    {
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().add(new PolygonPanel());
        setVisible(true);
    }
}
Genaugenommen ist das aber auch noch suboptimal: Wenn man "oft" die Größe ändert, macht sich auch der Effekt bemerkbar, dass Informationen durch das casten nach 'int' verlorengehen, und das Polygon "verzerrt" wird. Besser wäre es für solche Zwecke, das Polygon als eigene Klasse auf Basis von float-Daten zu speichern, und/oder sich IMMER das Originalpolygon aufzuheben, und den aktuellen Zustand (d.h. das skalierte Polgon) NUR zu zeichnen. Im Moment kannst du es nämlich drehen und wenden, wie du willst: Sobald das Polygon einmal auf "Breite 0" zusammengeschoben wurde, kriegt man es nie mehr auseinander......
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Zahlenwert durch Methode ersetzen Spiele- und Multimedia-Programmierung 1
D Iterieren durch einen Ordner mit Audiodateien und verketten eine andere Audiodatei Spiele- und Multimedia-Programmierung 17
A Spielfelder erstellen mit Jogl Java durch ein Koordinaten Array Spiele- und Multimedia-Programmierung 1
R Durch String Platform Game erstellen Spiele- und Multimedia-Programmierung 8
lord239123 JMonkey Schatten werden durch Terrain hindurch angezeigt Spiele- und Multimedia-Programmierung 1
R Mp3 Rating (POPM) durch JAudioTagger? Spiele- und Multimedia-Programmierung 2
M Objekte verschwinden durch Explosion Spiele- und Multimedia-Programmierung 2
B j3d Kamera Rotation durch Tastendruck Spiele- und Multimedia-Programmierung 12
I Framerate-Einbrüche durch Synchronisation Spiele- und Multimedia-Programmierung 12
E [JAVA3D] Schattenstrich durch die Szene Spiele- und Multimedia-Programmierung 4
N Zufallserzeugung durch KI Spiele- und Multimedia-Programmierung 23
H Grafik verschwindet durch Größenveränderung von GridBag Spiele- und Multimedia-Programmierung 5
S Hilfe: Ich sehe durch die ganze Api's nicht mehr durch! Spiele- und Multimedia-Programmierung 15
Fu3L Extreme Prozessorauslastung durch Hintergrundbild Spiele- und Multimedia-Programmierung 5
B Animation durch Button auslösen Spiele- und Multimedia-Programmierung 2
S Fehlerhafte Darstellung durch Transparenz? Spiele- und Multimedia-Programmierung 8
A durch Objekte hindurchzoomen Spiele- und Multimedia-Programmierung 2
masta // thomas Kollisionsabfrage - inspiriert durch "pixelgenaue Kolli Spiele- und Multimedia-Programmierung 13
E Durch Klick auf den JButton will ich die Farbe ändern? Spiele- und Multimedia-Programmierung 8
R Enorme Leistungseinbußen durch Alphakanäle Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen

Neue Themen


Oben