2D-Grafik schnelle Rotation

Hey Leute,
ich hätte mal eine Frage.

Diese lautet:
Ist es möglich in Java ein Bild (.svg-Datei also Vektorgrafik) so schnell zu drehen, dass es dem menschlichen Auge so vorkommt, dass es eine weiße Fläche ist. Wenn ja, wie und wenn nein, was für Tricks kann ich benutzen um diesen Effekt zu imitieren.

Ich freue mich schon auf eure Antworten:)
waterschlumpf

PS: Wenn ihr Code-Snippets braucht von meinem Programm bis jetzt melden. Allerdings wird bis jetzt nur die Grafik erzeugt.
 

bERt0r

Top Contributor
Verstehe nicht auf was du hinauswillst. Wenn du eine weiße Fläche zeichnen willst, dann tu das doch...
Wenn du ein Bild animieren willst, also drehen, wirst du einen Thread brauchen der in gewissen Abständen ein repaint ruft.
In deiner Paint kannst du mit AffineTransform Objekte drehen. Graphics2D.rotate geht auch und rotiert den ganzen Grafikbereich.
 
Ok ich hab mich vielleicht ungenau ausgedrückt.

Ich habe ein Programm entwickelt mit JFreeChart, in dem man die Sektoren verändern kann (Größe und Farbe). Es gibt einen Knopf mit dem Titel "Drehen". Dieser Knopf soll dieses Diagramm zum rotieren bringen und zwar so schnell, dass es dem Auge vorkommt als wäre eine weiße Fläche vorhanden wäre. Es soll die additive Farbmischung simulieren.


Der Code bis jetzt (Das mit dem Drehen und erzeugen ist in den Zeilen 27-106):
Java:
class PieChartDemo5 extends JFrame {
	private static final long serialVersionUID = 1L;
	public PieChartDemo5(String applicationTitle, String chartTitle) {
        super(applicationTitle);
         // This will create the dataset 
        PieDataset dataset = createDataset();
        // based on the dataset we create the chart
        final JFreeChart chart = createChart(dataset, chartTitle);
        // we put the chart into a panel
        ChartPanel chartPanel = new ChartPanel(chart);
        // default size
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 500));
        // add it to our application
        setContentPane(chartPanel);
        StandardChartTheme.createLegacyTheme();
        chart.setBackgroundPaint(Color.white);               
    	
        JFrame main = new JFrame("NATEXmische :: Hauptdialog");
		  main.setSize(500, 75) ;
      main.setLocation(190, 0);
      main.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      
     JButton drehenbutton = new JButton("Drehen");
      main.add(BorderLayout.SOUTH, drehenbutton);
      drehenbutton.addActionListener( new ActionListener() {
    	  public void actionPerformed( ActionEvent e ) {
    		// Get a DOMImplementation and create an XML document
    	        DOMImplementation domImpl =
    	            GenericDOMImplementation.getDOMImplementation();
    	        Document document = domImpl.createDocument(null, "svg", null);

    	        // Create an instance of the SVG Generator
    	        SVGGraphics2D svgGenerator = new SVGGraphics2D(document);

    	        // draw the chart in the SVG generator
    	        chart.draw(svgGenerator, new Rectangle2D.Double(0, 0, 500, 500));

    	        // Write svg file
    	        OutputStream outputStream = null;
				try {
					outputStream = new FileOutputStream("NATEXmische.svg");
				} catch (FileNotFoundException e5) {
					// TODO Auto-generated catch block
					e5.printStackTrace();
				}
    	        Writer out = null;
				try {
					out = new OutputStreamWriter(outputStream, "UTF-8");
				} catch (UnsupportedEncodingException e4) {
					// TODO Auto-generated catch block
					e4.printStackTrace();
				}
    	        try {
					svgGenerator.stream(out, true /* use css */);
				} catch (SVGGraphics2DIOException e3) {
					// TODO Auto-generated catch block
					e3.printStackTrace();
				}						
    	        try {
					outputStream.flush();
				} catch (IOException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
    	        try {
					outputStream.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

				
		        BufferedImage image = null;
				try {
					image = ImageIO.read(new File("NATEXmische.jpg"));
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
		        BufferedImage result = rotateImage(image, 45);
		        JFrame f = new JFrame();
		        ImageIcon i = new ImageIcon(result);
		        f.getContentPane().add(new JLabel(i));
		        f.pack();
		        f.setVisible(true);
    	       }
  		
		
	   private BufferedImage rotateImage(BufferedImage src, double degrees)
	    {
	        double w = src.getWidth();
	        double h = src.getHeight();
	        double sw = Math.ceil(src.getWidth() * Math.sqrt(2));
	        double sh = Math.ceil(src.getHeight() * Math.sqrt(2) / 2);
	        AffineTransform affineTransform = new AffineTransform();
	        affineTransform.translate(sw/2, sh/2);
	        affineTransform.rotate(Math.toRadians(degrees));
	        affineTransform.translate(-w/2, -h/2);
	        BufferedImage rotatedImage = new BufferedImage((int)sw, (int)sh, BufferedImage.TYPE_INT_BGR);
	        Graphics2D g = (Graphics2D)rotatedImage.createGraphics();
	        g.setTransform(affineTransform);
	        g.drawImage(src, 0, 0, null);
	        g.dispose();
	        return rotatedImage;
	        }
      }
	   
	    
		
		  
    	 );
           
      JMenuBar menuBar = new JMenuBar();
      JMenu fileMenu = new JMenu( "Datei" );
      
      fileMenu.addSeparator();

      fileMenu.add( new AbstractAction() {
        /**
			 * 
			 */
			private static final long serialVersionUID = 1L;
		{ putValue( Action.NAME,                         "Beenden" );
          putValue( Action.DISPLAYED_MNEMONIC_INDEX_KEY, 0 );
        }
        @Override public void actionPerformed( ActionEvent e ) {
          System.exit( 0 );
        }
      } );

      
      menuBar.add( fileMenu );
      
      JMenu helpMenu = new JMenu( "Hilfe" );
      
      helpMenu.add( new JMenuItem("Über...") );
      
      
      menuBar.add( helpMenu );
      
      main.setJMenuBar( menuBar );
      
      main.pack();
      main.setVisible(true);  
      
       
    }

            
/** * Creates a sample dataset */

    private PieDataset createDataset() {
        final DefaultPieDataset dataset = new DefaultPieDataset();
        dataset.setValue("Sektor 1", new Double(43.2));
        dataset.setValue("Sektor 2", new Double(10.0));
        dataset.setValue("Sektor 3", new Double(27.5));
        dataset.setValue("Sektor 4", new Double(17.5));
        dataset.setValue("Sektor 5", new Double(11.0));
        dataset.setValue("Sektor 6", new Double(19.4));
        dataset.setValue("Sektor 7", new Double(43.2));
        dataset.setValue("Sektor 8", new Double(10.0));
        dataset.setValue("Sektor 9", new Double(27.5));
        dataset.setValue("Sektor 10", new Double(17.5));
        dataset.setValue("Sektor 11", new Double(11.0));
        dataset.setValue("Sektor 12", new Double(19.4));
        
   
	    
[hier wird das Interface zu Farb und Größenauswahl initialisiert]
        
    }
}

public class V_0_3_6
{ public static void main( String[] args ) throws UnsupportedEncodingException, FileNotFoundException, SVGGraphics2DIOException
	  {PieChartDemo5 aktuelleEinstellungenWindow = new PieChartDemo5("", "");
		  aktuelleEinstellungenWindow.setTitle("NATEXmische :: Aktuelle Einstellungen");
		  aktuelleEinstellungenWindow.setLocation(190, 85);
		  aktuelleEinstellungenWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		  aktuelleEinstellungenWindow.pack();
		  aktuelleEinstellungenWindow.setVisible(true);}	}

Das Bufferd Image nicht mit .svg umgehen kann, hab ich heraus gefunden. Gibt es eine Alternative?
Und wie kann ich dafür sorgen, dass das Bild gedreht wird bis zu einem Knopfdruck?
 

bERt0r

Top Contributor
Schau das geht doch viel einfacher:
Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.JPanel;


public class RotatingPanel extends JPanel
{
	double rotation=0;
	/**
	 * Create the panel.
	 */
	public RotatingPanel()
	{
		
	}
	
	public void setRotation(double rotation)
	{
		this.rotation=rotation;
	}
	
	public double getRotation()
	{
		return rotation;
	}
	
	@Override
	public void paintComponent(Graphics g)
	{
		Graphics2D g2=(Graphics2D)g;
		Rectangle bounds=g.getClipBounds();
		
		g2.setColor(this.getBackground());
		g2.fill(bounds);
		
		g2.rotate(rotation,bounds.getCenterX(),bounds.getCenterY());
		super.paintComponent(g2);
	}
	
}

Und hier eine Demo-Klasse:
Java:
import java.awt.BorderLayout;


public class RotationPanelTest extends JFrame
{
	
	private JPanel contentPane;
	private RotatingPanel rotatingPanel;
	private JTable table;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					try
					{
						RotationPanelTest frame = new RotationPanelTest();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public RotationPanelTest()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		rotatingPanel = new RotatingPanel();
		rotatingPanel.setPreferredSize(new Dimension(200, 200));
		contentPane.add(rotatingPanel);
		rotatingPanel.setLayout(new BorderLayout(0, 0));
		
		JButton btnNewButton = new JButton("New button");
		rotatingPanel.add(btnNewButton, BorderLayout.NORTH);
		
		JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
		rotatingPanel.add(chckbxNewCheckBox, BorderLayout.WEST);
		
		JSpinner spinner = new JSpinner();
		rotatingPanel.add(spinner, BorderLayout.SOUTH);
		
		JScrollPane scrollPane = new JScrollPane();
		rotatingPanel.add(scrollPane, BorderLayout.CENTER);
		
		table = new JTable();
		table.setModel(new DefaultTableModel(
			new Object[][] {
				{null, null, null},
				{null, null, null},
				{null, null, null},
			},
			new String[] {
				"New column", "New column", "New column"
			}
		));
		scrollPane.setViewportView(table);
		
		JScrollPane scrollPane_1 = new JScrollPane();
		rotatingPanel.add(scrollPane_1, BorderLayout.EAST);
		
		JList list = new JList();
		list.setModel(new AbstractListModel() {
			String[] values = new String[] {"adsf", "sadf", "adsf", "adsf", "asdf"};
			public int getSize() {
				return values.length;
			}
			public Object getElementAt(int index) {
				return values[index];
			}
		});
		scrollPane_1.setViewportView(list);
		
		Thread t=new Thread()
		{
			@Override
			public void run()
			{
				while(true)
				{
					rotatingPanel.setRotation(rotatingPanel.getRotation()+1);
					rotatingPanel.repaint();
					try
					{
						Thread.sleep(40);
					} catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		t.start();
	}
	
}
 
S

Spacerat

Gast
Diesen Effekt wirst du schon programmtechnisch emulieren müssen. Grund dafür sind die jeweiligen Displays, die aktuell durchweg viel zu geringe Framerates haben. Kannst ja mal folgedes Video in Einzelbildern ansehen und hier posten, was dir auffält... richtig... Weisse Punkte, die sich eigentlich aus RGB zusammensetzen sind in den Bildern bereits weiss. Das liegt daran, dass hier eine normale Kamera schon irregeführt wird. Einer Highspeed-Kamera wäre das nicht passiert.
Nehmen wir mal an, eine Graka wäre eine solche Highspeed-Kamera, die mehrere 100 Frames pro Sekunde (ich lass die Zahl mal so undefiniert stehen, weil sie für diese Zwecke eigentlich unmenschlisch hoch sein müsste) aufnimmt. Ein Display würde sich trotzdem nur einen geringen Teil dieser Frames zur Darstellung herauspicken. Auf diesen wäre aber der Effekt nicht sichtbar.
 
Zuletzt bearbeitet von einem Moderator:
Vielen Dank die Drehfunktion hab ich implementiert mit einem Bild auf dem Panel. Jetzt werd ich mal eine Funktion mir ausarbeiten, die dann ein vordifiniertes Bild darüber blendet oder ein Script (welches ein Kreis mit einer bestimmten Farbe erzeugt) ausführt oder lasse ich es mir das erzeugnis ohne die drehen-simulation direkt anzeigen? Muss mal überlegen...

Tipps nehme ich immer entgeben.
 

Ähnliche Java Themen

Neue Themen


Oben