Morphing

mariusbopp

Bekanntes Mitglied
moin

habe folgendes problem, habe 1 start rechteck und ein ziel rechteck... und dazwischen sollen rechtecke gemorpht werden ( 1. is groß 2. kleiner..usw solange bis das ziel rechteck erreicht ist)

ich hab es mal sweit gemacht das ich ein start rechteck habe und das dann kleiner morphe aber das ist knapp vorbei geziehlt^^

kann mir jemand mal beim denken helfen :eek:
 

mariusbopp

Bekanntes Mitglied
worauf ist das wobei bezogen?^^

Java:
Graphics2D g2 = (Graphics2D)g;
		        int a=0, b = 0, c = 0;
		        
		        for(int i=1;i<=10;i++){
				      a=a+10;
				      b=b+5;
				      c = c + 25;
				      g2.setColor(new Color(0+c, 0, 255-c));
				      g2.fillRect(x+a, y+a, width-b, height-b);
				}
			}

das ganze dann auf ein jFrame gelegt...

aber das ist ja nicht das ziel die ausgabe ist zwar exakt so wie es aussehen soll aber es soll ja vom start zum ziel rechteck und nicht einfach nur vom start bis belibige wiederholungen (im dem fall 10)
 

Michael...

Top Contributor
Letztendlich muss man ja entweder die Dauer und Schrittanzahl des Morphings oder die Schrittanzahl und Verzögerung je Schritt vorgeben.

Und der gepostete Code zeigt tatsächlich die einzelnen Schritte an? Für mich schaut das ein bisschen merkwürdig aus.
 

mariusbopp

Bekanntes Mitglied
ja also es "morpht" richtig^^ es gibt quasi 10 mal das rechteck aus nur position erhöt sich und größe verringert sich... keine ahnung wie ich hier n bild hoch laden kann sonst würde ich dir ma mein ausgabe fenster zeigen!!
 

Michael...

Top Contributor
Kann mir das jetzt schwer vorstellen, dass es funktioniert. Aber wenn Du's sagst muss ich es wohl glauben ;-)

Hier mal ein Bsp. wie ich das Morphing angehen würde. (Ist nur mal schnell runtergeschrieben und soll meinen Ansatz verdeutlichen) In einem eigenen Thread werden in jedem Schleifendurchlauf Größe und Farbe des "nächsten" Rechtecks berechnet, danach wird entsprechend des angegebenen Delays pausiert.
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.*;

public class MorphingRect extends JFrame {
	
	public MorphingRect() {
		MorphingPanel mPanel = new MorphingPanel(
				new Rectangle(0, 0, 100, 200), Color.YELLOW,
				new Rectangle(0, 0, 200, 100), Color.BLUE,
				50, 100
			);
		this.getContentPane().add(mPanel);
		new Thread(mPanel).start();
	}
	
	class MorphingPanel extends JPanel implements Runnable {
		private Rectangle rect1, rect2;
		private Color color1, color2;
		private int steps, delay;
		
		private Rectangle rect;
		private Color color;
		
		public MorphingPanel(Rectangle rect1, Color color1, Rectangle rect2, Color color2, int steps, int delay) {
			this.rect1 = rect1;
			this.rect2 = rect2;
			this.color1 = color1;
			this.color2 = color2;
			this.steps = steps;
			this.delay = delay;
			
			this.color = new Color(color1.getRGB());
			this.rect = new Rectangle(0, 0, rect1.width, rect1.height);
		}
		
		public void run() {
			for(int i=1; i<steps; i++) {
				try {
					Thread.sleep(delay);
					rect.width = rect1.width - (rect1.width - rect2.width)*i/steps;
					rect.height = rect1.height - (rect1.height - rect2.height)*i/steps;
					color = new Color(
							color1.getRed() - (color1.getRed()- color2.getRed())*i/steps,
							color1.getGreen() - (color1.getGreen()- color2.getGreen())*i/steps,
							color1.getBlue() - (color1.getBlue()- color2.getBlue())*i/steps
							);
					
					repaint();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.setColor(color);
			Graphics2D g2 = (Graphics2D)g;
			rect.x = (this.getWidth() - rect.width)/2;
			rect.y = (this.getHeight() - rect.height)/2;
			g2.fill(rect);
		}
	}
	
	public static void main(String[] args) {
		JFrame frame = new MorphingRect();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

mariusbopp

Bekanntes Mitglied
ahhh cool aber das ist nicht das was ich brauche! und zwar ist das letze(also vorgänger rechteck) noch da !!

habs mal hoch geladen so meine ich das

vill war es etwas schlecht erklärt! oder ist morphing das falsche wort dafür?
 

Michael...

Top Contributor
Ah jetzt hab ich verstanden was Du vorhast. Grundsätzlich kannst Du ja meine Berechnung der "Zwischenschritte" übernehmen - muss halt noch um die Berechnung von x und y erweitern.
Das Thema Thread und Delay kannst Du dann vergessen.
 

mariusbopp

Bekanntes Mitglied
ja hab ich mir nämlich fast gedacht das wir grade aneinander vorbei reden... aber der code von dir scheribt ja dann immer ein neues rechteck und das alte ist "weg" richtig?!

aber jetzt hast du verstanten wie ich es machen muss oder?! rechteck 1 -----> rechteck 2 und die zwischenschritte mit ausgeben ... :toll:

ich bin grade dabei mir deinen code mal umzu basteln aber irgendwie steh ich auf m schlauch:noe:
 

Michael...

Top Contributor
Ich würde die Zwischenschritte in einer Liste speichern oder das ganz auf ein BufferedImage zeichnen.
Beim Zeichnen arbeitest Du dann entweder die Liste ab oder malst das Image.
 

mariusbopp

Bekanntes Mitglied
okay ja soweit bin ich jetzt auch gekommen ich könnte dann die einzelnen schritte in ein array speichern??
Java:
Rectangle rechtecke[] = new Rectangle[i];
			rechtecke[1]=r;

würde das so gehen??
edit: er speichert ja dann quasi
Code:
x= 110  y= 110  width= 50  height= 50
in einem feld richtig?
die kann man ja dann quasie so erstellen wie ich es oben gemacht hab... ?

aber wie sag ich dem wann das letze rechteck erreicht ist?

kann ich dann einfach n vergleich machen "graphics 1==graphics 2"?
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Ja das geht. Ich würde aber eine ArrayList nehmen, ist flexibler.
Java:
ArrayList<Rectangle> rechtecke = new ArrayList<Rectangle>();
 

mariusbopp

Bekanntes Mitglied
okay nächste frage... ich hab es jetzt einfach mal schnell in ein array geschrieben, also die werte vom start rechteck und vom zeil rechteck. zwischen schritte hab ich noch keine gemacht...

aaaaber er schreibt für jedes feld die werte 2 mal rein
Java:
Rectangle rechtecke[] = new Rectangle[5];
        rechtecke[1]=r1;
       System.out.println(rechtecke[1]);
ergibt:
Code:
java.awt.Rectangle[x=10,y=10,width=150,height=150]
java.awt.Rectangle[x=10,y=10,width=150,height=150]

die ausgabe der rechtecke...:applaus:
 

Michael...

Top Contributor
Wie gesagt ohne Code lassen sich Fehler schwer erkennen ;-)

Hier mal das abgeänderte Bsp, damit es Deinem Morphing entspricht. Hier werden wieder die selben Algorithmen genutzt, um die Zwischenschritte zu berechnen, die Ergebnisse werden in einer Rechteck- und Farbenliste gespeichert, die dann in der paintComponent abgearbeitet werden.
Mit dem Slider rechts kann man die Anzahl der Zwischenschritte variieren.
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MorphingRect extends JFrame {
	private MorphingPanel2 mPanel;
	
	public MorphingRect() {
		mPanel = new MorphingPanel2(
				new Rectangle(10, 10, 300, 300), Color.YELLOW,
				new Rectangle(210, 210, 180, 150), Color.BLUE,
				10
			);
		JSlider slider = new JSlider(JSlider.VERTICAL, 0, 50, 10);
		slider.setMajorTickSpacing(10);
		slider.setPaintLabels(true);
		slider.setPaintTicks(true);
		slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				mPanel.setSteps(((JSlider) e.getSource()).getValue());
			}
		});
		this.getContentPane().add(mPanel, BorderLayout.CENTER);
		this.getContentPane().add(slider, BorderLayout.EAST);
	}
	
	class MorphingPanel2 extends JPanel {
		private ArrayList<Rectangle> rectList;
		private ArrayList<Color> colorList;
		private Rectangle rect1, rect2;
		private Color color1, color2;
		
		public MorphingPanel2(Rectangle rect1, Color color1, Rectangle rect2, Color color2, int steps) {
			this.rect1 = rect1;
			this.color1 = color1;
			this.rect2 = rect2;
			this.color2 = color2;
			setSteps(steps);
		}
		
		public void setSteps(int steps) {
			rectList = new ArrayList<Rectangle>();
			colorList = new ArrayList<Color>();
			rectList.add(rect1);
			colorList.add(color1);
			for(int i=1; i<steps; i++) {
				int x = rect1.x - (rect1.x - rect2.x)*i/steps;
				int y = rect1.y - (rect1.y - rect2.y)*i/steps;
				int w = rect1.width - (rect1.width - rect2.width)*i/steps;
				int h = rect1.height - (rect1.height - rect2.height)*i/steps;
				rectList.add(new Rectangle(x, y, w, h));
				Color color = new Color(
						color1.getRed() - (color1.getRed()- color2.getRed())*i/steps,
						color1.getGreen() - (color1.getGreen()- color2.getGreen())*i/steps,
						color1.getBlue() - (color1.getBlue()- color2.getBlue())*i/steps);
				colorList.add(color);
			}
			rectList.add(rect2);
			colorList.add(color2);
			repaint();
		}
		
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			Graphics2D g2 = (Graphics2D)g.create();
			for (int i=0; i<rectList.size(); i++) {
				g2.setColor(colorList.get(i));
				g2.fill(rectList.get(i));
			}
			g2.dispose();
		}
	}
		
	public static void main(String[] args) {
		JFrame frame = new MorphingRect();
		frame.setBounds(0, 0, 600, 400);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

mariusbopp

Bekanntes Mitglied
okay sieht schonmal toll aus :)

aber wieso gibt rectangel die koordinaten undt größe 2 mal zurück auf der konsole???

(also in meinem programm meine ich)

ich gebe einefach sysout(r1); aus das ist das erste rechteck...:bahnhof:

puhh...
 

mariusbopp

Bekanntes Mitglied
ich glaube ich hab es gefunden^^
Java:
import java.awt.*;

import javax.swing.*;
 
public class Rechteck extends JPanel {
 
    public void paintComponent(Graphics g){
 
        int x = 10;
        int y = 10;
        int width = 150;
        int height = 150;
 
        Rectangle r1 = new Rectangle(x, y, width, height);
        Rectangle r2 = new Rectangle(x+100, y+100, width-65, height-65);
  
        //rechteck 1
        Graphics2D g2 = (Graphics2D)g;
        
        g2.setColor(new Color(20, 0, 200));
        g2.fill(r1);
        
        g2.setColor(new Color(199, 21, 133));
        g2.fill(r2);
        
        
        Rectangle rechtecke[] = new Rectangle[5];
        rechtecke[1]=r1;
        rechtecke[2]=r2;
        System.out.println(rechtecke[1]);
        System.out.println(rechtecke[2]);
.
.
.
.

und zwar weil ich 2 mal g2 benutze um die rechtecke zu erzeugen?!?:eek:

ich versuche mich grade erst ganz neu an awt und naja dementsprechent sieht der code aus:oops:
 

André Uhres

Top Contributor
und zwar weil ich 2 mal g2 benutze um die rechtecke zu erzeugen?!?:eek:
Hallo mariusbopp,

das System ruft automatisch die paintComponent Methode der Komponente auf, wenn aus irgendeinem Grund neu gezeichnet werden muss.

Die Ausgabe erfolgt doppelt, weil das System paintComponent zweimal aufruft. Dass zu Beginn zweimal gemalt wird, mag vielleicht auf das Betriebssystem zurückzuführen sein, oder vielleicht muss das System die Komponente zuerst darstellbar machen und dann erst sichtbar, was wohl ebenfalls zwei Malvorgänge bedeuten würde.

In paintComponent sollten wir außerdem "teure" Sachen vermeiden wollen, wie z.B Bilder laden, Datenbank lesen, neue Objekte erzeugen, ... In deinem Beispiel werden neue Objekte erzeugt, was nicht gut ist.

Siehe auch: Malen in Swing Teil 1: der grundlegende Mechanismus - Byte-Welt Wiki

Gruß,
André
 

mariusbopp

Bekanntes Mitglied
hallo andrè

ja sowas habe ich mir schon fast gedacht :)
hab erst mit awt und co angefangen deswegen sieht das noch so aus!

ich wusste halt nicht wie ich da vorgehen sollte und da hab ich halt einfach mal probiert und joa er ja auch erstmal das gemacht was es sollte! das es nicht so sauber is hab ich mir auch überlegt!
werde mir mal deinen link durchlesen :)

dankeschön
 

Neue Themen


Oben