Linie von Kreisen

M

Mathe-Problem

Gast
Hallo,
ich möchte Kreise Zeichnen...

Konkret habe ich eine Linie von Kreisen (leicht versetzt)

Diese Gruppe von Reisen möchte ich quasi kopieren und um einen bestimmten winkel versetzt noch einmal anordnen.

Bilder sagen manchmal mehr wie Worte:

60986509.png


Die 20 Kreise nach rechts sind Vorgegeben nun stellt man sich vor das diese Gruppe um den Winkel x gedreht und auch dort eingefügt werden soll.

Ich komm anscheinend mit der Formal nicht zurecht... (bei 45° stimmt es ja definitiv nicht)

Java:
        int ledsize=16;
        double winkel=0;
        int abstandx=2;
        int abstandy=4;
        double x_pos;
        double y_pos;
        int count; //Schleifendurchläufe

        
        //Berechnen
        x_pos = ((0*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
        y_pos= ((0*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
        //Zeichnen
        g.drawOval((int)x_pos,(int)y_pos ,ledsize ,	ledsize);
        
        for (winkel=0; winkel<360; winkel=winkel+1.8)
        {
	        for (int x_inc=0; x_inc<342; x_inc=x_inc+(ledsize+ abstandx))
	        {
	        	count=x_inc/(ledsize+ abstandx);
	        	if (count%2==0)
	        	{ 
	        		x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
	        		y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
	        	}
	        	else
	        	{
	        		x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
	        		y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
	        	}
	        	
	        	//Zeichnen
	        	g.drawOval((int)x_pos,(int)y_pos ,ledsize ,	ledsize);
	        }
        }

berichtige ich das ganze das auch bei 45° ein sauberes Bild entsteht?
 
Zuletzt bearbeitet von einem Moderator:

tribalup

Bekanntes Mitglied
Warum berechnest du bei x_pos und y_pos 0*......?

Hab leider keine Zeit mehr aber vielleicht hilft es dir ja wenn ich dir sage dass dein Ansatz auf dem Bild oben schon nicht stimmt denn das Ursprungsbild wird nicht um einen Winkel gedreht.
Schau dir bspw. die Kreise nach rechts und nach oben an. Das ist nicht gedreht.
 
Zuletzt bearbeitet:
M

Mathe-Problem

Gast
hm. gute Frage ich steh grade auch eher im Wald ...


die Zeilen sind, so denke ich, am interessantesten:
Java:
 if (count%2==0)
                { 
                    x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
                    y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
                }
                else
                {
                    x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
                    y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
                }
 
P

pappawinni

Gast
Hm.. äh..Hab ja noch keine Graphik in Java gamacht, aber die Kreise,
wie sind die denn positioniert, über den Mittelpunkt, oder vielleicht über einen Eckpunkt??

Ich meine mich zu erinnern, dass jemand in Java einen Kreis zeichnen wollte und musste dazu die
Linke obere Ecke und die Seitenlänge der Box um den Kreis angeben, oder so.
Wenn du also sowas drehen willst, müsstest du erst zum Kreismittelpunkt rechnen, den drehen,
dann wieder zurück zur Ecke der Box rechnen, sonst gibt es Verzerrungen.

[EDIT]Es war DrawOval. Da würde das Gesagte zutreffen.
DrawOval
Parameters:
x - left edge of the rectangle
y - top edge of the rectange
width - width of the rectangle
height - height of the rectange[/EDIT]

[EDIT]Klar, DrawOval, steht ja Code. Da ham wir das Problem dann wohl auch schon, oder?

Mach doch mal einfach

g.drawOval((int)x_pos - ledsize/2, (int)y_pos + ledsize/2, ledsize , ledsize);

[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
M

Mathe-Problem

Gast
ne das ist nicht das Problem wird schon berücksichtigt

Java:
x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(abstandy-0))[B]-ledsize/2;[/B]
 
P

pappawinni

Gast
Java:
               int ledsize=16;
                double winkel=0;
                int abstandx=2;
                int abstandy=4;
                double x_pos;
                double y_pos;
                int count; //Schleifendurchläufe

                x_pos = Jframe_width/2-ledsize/2;
                y_pos = Jframe_height/2-ledsize/2;

                g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);

                
                for (winkel=0; winkel<360; winkel=winkel+30)
                {  
                    double anglerad = Math.toRadians(winkel);
                    double sinang = Math.sin(anglerad);
                    double cosang = Math.cos(anglerad);
                    for (int x_inc=0; x_inc< 19*(ledsize + abstandx); x_inc=x_inc+(ledsize+ abstandx))
                    {
                        count=x_inc/(ledsize+ abstandx);
                        if (count%2==0)
                        { 
                        	double dx = (ledsize+abstandx+x_inc);
                        	double dy = abstandy;
                        	x_pos= cosang*dx - sinang*dy + Jframe_width/2 - ledsize/2;
                            y_pos= sinang*dx + cosang*dy + Jframe_height/2 - ledsize/2;
                        }
                        else
                        {
                        	double dx = (ledsize+abstandx+x_inc);
                        	// dy =0;
                            x_pos =cosang*dx+Jframe_width/2-ledsize/2;
                            y_pos =sinang*dx+Jframe_height/2-ledsize/2;

                        }
                        
                        //Zeichnen
                        g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);
                    }
                }
 

Anhänge

  • drawovalexample.jpg
    drawovalexample.jpg
    47,8 KB · Aufrufe: 42
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Sorry, OT, aber ... Mathematische Wurzeln hin oder her, aber wie wenig ... (was auch immer) ist notwendig, um auf die Idee zu kommen aus Zeilen wie
Java:
                if (count%2==0)
                { 
                    x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
                    y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(abstandy-0))-ledsize/2;
                }
                else
                {
                    x_pos= (((ledsize+abstandx+x_inc)*Math.cos(winkel/180*Math.PI)+Jframe_width/2)+Math.sin(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
                    y_pos= (((ledsize+abstandx+x_inc)*Math.sin(winkel/180*Math.PI)+Jframe_height/2)+Math.cos(winkel*Math.PI/180)*(0-abstandy))-ledsize/2;
                }
sowas zu machen wie
Java:
                    double anglerad = Math.toRadians(winkel);
                    double sinang = Math.sin(anglerad);
                    double cosang = Math.cos(anglerad);
....
                            x_pos= cosang*dx - sinang*dy + Jframe_width/2 - ledsize/2;
                            y_pos= sinang*dx + cosang*dy + Jframe_height/2 - ledsize/2;
?!
(Es ginge wohl noch einfacher, aber das fiel mir nur beim Überfliegen auf...)
 
P

pappawinni

Gast
Naja, man kann natürlich auch die beiden Abstände separat betrachten.
Gewissermassen einen X-Abstand und einen Y-Abstand der Ursprungreihe als einzelne Vektoren rotieren und hat dann einen "rotierten X-Vektor" und einen "rotierten Y-Vektor".
Um die Reihe von Kreisen zu zeichnen, muss man dann nur Vielfache des "rotierten X-Vektor" bilden und nur in jedem 2ten Fall den "rotierten Y-Vektor" addieren.
Nach der Rotation muss man das Ganze natürlich noch an die richtige Position schieben.

Ob das so dann noch viele Vorteile bringt, keine Ahnung:

Java:
                int ledsize=16;
                double winkel=0;
                int abstandx=2;
                int abstandy=4;
                double x_pos;
                double y_pos;

                x_pos = Jframe_width/2-ledsize/2;
                y_pos = Jframe_height/2-ledsize/2;

                g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);

                
                for (winkel=0; winkel<360; winkel=winkel+30)
                {  
                    double anglerad = Math.toRadians(winkel);
                    double sinang = Math.sin(anglerad);
                    double cosang = Math.cos(anglerad);
                    /* Rotation y-Komponente */                    
                    double vdyx= - sinang * abstandy;
                    double vdyy = cosang * abstandy;
                    /* Rotation x-Komponente */
                    double vdxx = cosang * (abstandx+ledsize);
                    double vdxy=  sinang * (abstandx+ledsize);
                    
                    for (int x_inc=1; x_inc< 20; x_inc++)
                    {
                        /* rotierte X-Komponente auf Länge bringen */
                    	x_pos = x_inc * vdxx;                    	
                        y_pos = x_inc * vdxy;
                        
                        if (x_inc%2==1)
                        { 
                        	/* in jedem 2ten Fall die rotierte Y-Komponente addieren */
                            x_pos += vdyx;
                        	y_pos += vdyy;                            
                        }
                        /* Verschiebung */
                        x_pos += Jframe_width/2-ledsize/2;
                        y_pos += Jframe_height/2-ledsize/2;   
                        
                        //Zeichnen
                        g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);
                    }
                }
 

Marco13

Top Contributor
Ich meinte, dass man sich viel von den Winkelberechnungen sparen könnte... grob (!) mit sowas wie
Java:
package javaforum;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CirclePainter
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new CirclePainterPanel());
        f.setSize(400,400);
        f.setVisible(true);
    }
}


class CirclePainterPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        AffineTransform oldAT = g.getTransform();
        g.translate(getWidth()/2.0, getHeight()/2.0);
        
        for (int i=0; i<8; i++)
        {
            g.rotate(Math.toRadians(45));
            drawRay(g);
        }
        g.setTransform(oldAT);
    }
    
    private static void drawRay(Graphics2D g)
    {
        for (int x=0; x<20; x++)
        {
            g.draw(new Ellipse2D.Double(x*40, -5, 16, 16));
            g.draw(new Ellipse2D.Double(x*40+20, 5, 16, 16));
        }
    }
}
... kommt halt drauf an, worum es geht...
 
P

pappawinni

Gast
Und jetzt hätt ich gerne mal nen Geschwindigkeitsvergleich.
Darin bist du doch der Meister. Lass ma sehen :D
 

Marco13

Top Contributor
Ja, es ist anzunehmen, dass es theoretisch (!) "schneller" ist, die Ovale (mit int-Koordinaten, in ein untransformiertes Graphics) manuell zu zeichnen. Aber man kann es praktisch nicht vernünftig messen, weil ... nun, es geht darum ein paar hundert Kreise zu zeichen ... ;)

Und außerdem ...
Java:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CirclePainter
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().setLayout(new GridLayout(1,0));
        f.getContentPane().add(new CirclePainterPanel());
        f.setSize(1000,1000);
        f.setVisible(true);
    }
}


class CirclePainterPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        AffineTransform oldAT = g.getTransform();
        g.translate(getWidth()/2.0, getHeight()/2.0);
        
        for (int i=0; i<12; i++)
        {
            g.rotate(Math.toRadians(45));
            drawRay(g);
        }
        g.setTransform(oldAT);
    }
    
    private static void drawRay(Graphics2D g)
    {
        for (int i=0; i<30; i++)
        {
            float x = (float)(Math.pow(1.1, i)-1);
            float y = (float)(Math.sin(x*0.9) * 15);
            g.draw(new Ellipse2D.Double(x*20, y, 16, 16));
        }
    }
}

IN YOUR FACE! :cool: :bae:
 
M

Mathe-Problem

Gast
danke das klappt ja schon ganz wunderbar...

ich stehe nun grad vor den Problem das ich mit
Java:
class MyMotionListener
extends MouseMotionAdapter
{	
	public int x_mouse=0;
	public int y_mouse=0;
	
	public void mouseMoved(MouseEvent m)
	{
		x_mouse = m.getX();
		y_mouse = m.getY();
	}
}

die aktuelle position meiner maus feststelle.
bin ich genau auf den zentrum eines kreises möchte ich ihn färben

nun kann ich aber aus der "zeichnen klasse" nicht auf die "mauspositionsklasse" zugreifen...

ich habe also die punkte und weis auch wo ich den kreis hinzeichnen möchte.
ich kann aber aber aus class MyMotionListener leider nicht

könnte ich mir bitte noch einmal helfen?
 
M

Mathe-Problem

Gast
nochmal kompletter Code

Java:
import java.awt.Color;

import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Uebung9 extends JFrame{
	static int Jframe_width=750;
	static int Jframe_height=750;
	
	static int array_x[][]; //Enthält die x-koordinaten [0][1] = Zeile 1 und 2. LED pos
	static int array_y[][]; //Enthält die y-koordinaten...
	
	MyMotionListener m = new MyMotionListener();
	
    public Uebung9(String newTitel) {
        super.setTitle(newTitel);
        addMouseMotionListener(m);
    }
    
    public static void main(String str[]) {
        Uebung9 fenster = new Uebung9("Test");
        fenster.setSize(Jframe_width, Jframe_height);
        fenster.setVisible(true);
    }
    
    
    
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(new Color(0, 0, 0));
        
        int ledsize=16;
        double winkel=0;
        int abstandx=2;
        int abstandy=4;
        double x_pos;
        double y_pos;
        double ink=90;
        int count; //Schleifendurchläufe

        array_x = new int[(int)(360/ink)][20];
        array_y = new int[(int)(360/ink)][20];
        
        x_pos = Jframe_width/2-ledsize/2;
        y_pos = Jframe_height/2-ledsize/2+15;

        g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);
        
        
        for (winkel=0; winkel<360; winkel=winkel+ink)
        {  
            double anglerad = Math.toRadians(winkel);
            double sinang = Math.sin(anglerad);
            double cosang = Math.cos(anglerad);
            for (int x_inc=0; x_inc< 19*(ledsize + abstandx); x_inc=x_inc+(ledsize+ abstandx))
            {
                count=x_inc/(ledsize+ abstandx);
                if (count%2==0)
                { 
                    double dx = (ledsize+abstandx+x_inc);
                    double dy = abstandy;
                    x_pos= cosang*dx - sinang*dy + Jframe_width/2 - ledsize/2;
                    y_pos= sinang*dx + cosang*dy + Jframe_height/2 - ledsize/2+15;
                }
                else
                {
                    double dx = (ledsize+abstandx+x_inc);
                    // dy =0;
                    x_pos =cosang*dx+Jframe_width/2-ledsize/2;
                    y_pos =sinang*dx+Jframe_height/2-ledsize/2+15;

                }
                
                //Zeichnen
                double temp=winkel/ink;
                array_x[(int)temp][count]= (int)x_pos-ledsize/2;
                array_y[(int)temp][count]= (int)y_pos-ledsize/2;
                g.drawOval((int)x_pos,(int)y_pos ,ledsize , ledsize);
            }
        }
    }
}

class MyMotionListener
extends MouseMotionAdapter
{	
	public int x_mouse=0;
	public int y_mouse=0;
	
	public void mouseMoved(MouseEvent m)
	{
		x_mouse = m.getX();
		y_mouse = m.getY();
	}
}
 

Marco13

Top Contributor
Mach' mal die ganzen statics weg.

Vermutlich wäre es auch einfacher und eleganter, die Arrays NICHT bei jedem Neuzeichnen neu zu erstellen.

Aber zum eigentlichen Problem: GANZ grob und sinngemäß muss man die Arrays "irgendwie" in der Listener-Klasse bekannt machen. Wirklich SEHR pragmatisch wäre, dort, wo die Arrays erstellt werden, sowas zu machen wie

Java:
myListener.setArrays(xArray, yArray);

// Wobei die Klasse so aussieht
class MyListener
{
    private int xArray[];
    private int yArray[];

    public void setArrays(int xArray[], int yArray[])
    {
        this.xArray = xArray;
        this.yArray = yArray;
    }

...


AAAABER ... das ist sehr häßlich und un-elegant :autsch: Du solltest ggf. mal die genaue Aufgabenstellung posten, da gibt's bestimmt schönere Lösungen.
 
P

pappawinni

Gast
Hm, ich dacht mir auch, dass das nicht unbedingt notwendig ist, bei jedem neu Zeichnen die Positionen neu zu bestimmen.
Jetzt hab ich mich mal an einem Applet mit ner Arraylist versucht, beides bisher noch nicht gemacht.

Jetzt hab ich natürlich keine Ahnung wie ich da nen Maus-Event rein kriege, der mir die Position sagt, die dann in der Liste der Mittelpunkte gesucht werden müsste um dann von voll auf ungefüllt umzuschalten und umgekehrt.
Ein Repaint wird es dann wohl auch noch brauchen, irgendwie.

Java:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.*;

public class DrawOvalsExample extends Applet{
	private static final long serialVersionUID = 1L;

    List<Object> list = new ArrayList<Object>();
    int ledsize=16;
    int Jframe_height;
    int Jframe_width;
    
	
		public void init(){
            Jframe_height = this.getSize().height;
            Jframe_width = this.getSize().width;			
            double winkel=0;
            int abstandx=2;
            int abstandy=4;
            double x_pos;
            double y_pos;

            x_pos = 0;
            y_pos = 0;
            list.add(new int[] {(int) x_pos,(int)y_pos,0});
            
            for (winkel=0; winkel<360; winkel=winkel+30)
            {  
                double anglerad = Math.toRadians(winkel);
                double sinang = Math.sin(anglerad);
                double cosang = Math.cos(anglerad);
                /* Rotation y-Komponente */                    
                double vdyx= - sinang * abstandy;
                double vdyy = cosang * abstandy;
                /* Rotation x-Komponente */
                double vdxx = cosang * (abstandx+ledsize);
                double vdxy=  sinang * (abstandx+ledsize);
                
                for (int x_inc=1; x_inc< 20; x_inc++)
                {
                    /* rotierte X-Komponente auf Länge bringen */
                	x_pos = x_inc * vdxx;                    	
                    y_pos = x_inc * vdxy;
                    
                    if (x_inc%2==1)
                    { 
                    	/* in jedem 2ten Fall die rotierte Y-Komponente addieren */
                        x_pos += vdyx;
                    	y_pos += vdyy;                            
                    }
                    /* Verschiebung */
                    list.add(new int[] {(int) x_pos,(int)y_pos,0});
                }
            }
                    
		}
	    public void paint(Graphics g){

                //set color to red
                Jframe_height = this.getSize().height;
                Jframe_width = this.getSize().width;			
                setForeground(Color.red);
                
                ListIterator<Object> it = list.listIterator();
            	int[] pinf = {0,0,0};
                while (it.hasNext()){
                	pinf = (int[]) it.next();
                    if (pinf[2]==0){
                    	g.drawOval(pinf[0]+Jframe_width/2-ledsize/2,
                        		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                    }
                    else
                    {
                        g.fillOval(pinf[0]+Jframe_width/2-ledsize/2,
                        		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                        	
                    }
                }
                
       }
}
 
Zuletzt bearbeitet von einem Moderator:
P

pappawinni

Gast
Naja, irgendwie funktioniert das schon,
ob das jetzt elegant ist, oder auch nicht:

Java:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.*;
import java.awt.event.*; 

public class DrawOvalsExample extends Applet implements MouseMotionListener {
	private static final long serialVersionUID = 1L;

    List<Object> list = new ArrayList<Object>();
    int ledsize=16;
    int Jframe_height;
    int Jframe_width;
    
	
		public void init(){
            Jframe_height = this.getSize().height;
            Jframe_width = this.getSize().width;			
            double winkel=0;
            int abstandx=2;
            int abstandy=4;
            double x_pos;
            double y_pos;

            x_pos = 0;
            y_pos = 0;
            list.add(new int[] {(int) x_pos,(int)y_pos,-1});
            
            for (winkel=0; winkel<360; winkel=winkel+30)
            {  
                double anglerad = Math.toRadians(winkel);
                double sinang = Math.sin(anglerad);
                double cosang = Math.cos(anglerad);
                /* Rotation y-Komponente */                    
                double vdyx= - sinang * abstandy;
                double vdyy = cosang * abstandy;
                /* Rotation x-Komponente */
                double vdxx = cosang * (abstandx+ledsize);
                double vdxy=  sinang * (abstandx+ledsize);
                
                for (int x_inc=1; x_inc< 20; x_inc++)
                {
                    /* rotierte X-Komponente auf Länge bringen */
                	x_pos = x_inc * vdxx;                    	
                    y_pos = x_inc * vdxy;
                    
                    if (x_inc%2==1)
                    { 
                    	/* in jedem 2ten Fall die rotierte Y-Komponente addieren */
                        x_pos += vdyx;
                    	y_pos += vdyy;                            
                    }
                    /* Verschiebung */
                    list.add(new int[] {(int) x_pos,(int)y_pos,-1});
                }
            }
            addMouseMotionListener(this); 
                    
		}
	    public void paint(Graphics g){

                //set color to red
                Jframe_height = this.getSize().height;
                Jframe_width = this.getSize().width;			
                setForeground(Color.red);
                
                ListIterator<Object> it = list.listIterator();
            	int[] pinf = {0,0,0};
                while (it.hasNext()){
                	pinf = (int[]) it.next();
                    if (pinf[2]<0){
                    	g.drawOval(pinf[0]+Jframe_width/2-ledsize/2,
                        		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                    }
                    else
                    {
                        g.fillOval(pinf[0]+Jframe_width/2-ledsize/2,
                        		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                        	
                    }
                }
                
       }
	    public void mouseMoved(MouseEvent me)  
	     {  
	          int posX = me.getX()-Jframe_width/2; 
	          int posY = me.getY()-Jframe_height/2; 
	          
              ListIterator<Object> it = list.listIterator();
              int[] pinf = {0,0,0};
              while (it.hasNext()){
              	pinf = (int[]) it.next();
                  if (pinf[0]==posX && pinf[1]==posY){
                	  it.set(new int[] {pinf[0],pinf[1],-pinf[2]});
        	          repaint(); 
                	  break;
                  }
              }


	     } 
	    public void mouseDragged(MouseEvent me)  
	     { 
	     } 


}
 

Crian

Top Contributor
Die Variablennamen sind allerdings alles andere als schön.

Was genau macht der Mouselistener? Bei mir passiert nichts, was über die Maus ausgelöst würde.
 
P

pappawinni

Gast
Wenn du die Maus über den Mittelpunkt eines Kreises bewegst, sollte sich was tun.
Nur drüber bewegen, nix klicken oder so.

[EDIT]Die Arraylist enthält Integer Arrays. Jedes dieser Arrays hat 3 Komponenten.
x und y Koordinaten der Kreismittelpunkte (ohne Verschiebung) und als dritte Komponente eine 1 oder -1.
Die Paint-Methode zeichnet die Kreise anhand der ArrayList auf die Mitte des Fensters verschoben und abhängig von der dritten Komponente das Int-Array als gefüllten oder ungefüllten Kreis.
Der MouseListener schaut nur, ob die Maus über einem Kreismittelpunkt ist, kehrt dann für den entsprechenden Kreis den dritten Wert des Int-Array um und sorgt dann mittels repaint() dafür, dass paint ausgeführt wird.[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

Crian

Top Contributor
Wenn du die Maus über den Mittelpunkt eines Kreises bewegst, sollte sich was tun.
Nur drüber bewegen, nix klicken oder so.

Tatsächlich, da muss man aber sehr genau die Mitte treffen.


[EDIT]Vielleicht kannst du dafür diese Methode aus einer eigenen Kreisklasse von mir gebrauchen?

Java:
    /**
     * Ermittelt, ob der übergebene Punkt auf der Kreislinie oder innerhalb
     * davon liegt.
     *
     * @param point
     *            Zu überprüfender Punkt.
     * @return Wahrheitswert.
     */
    public boolean incloses(Point point) {
        double pointX = point.getX();
        double pointY = point.getY();

        double centerX = center.getX();
        double centerY = center.getY();

        /*
         * Falls der Klick außerhalb des umschließenden Quadrats ist, gleich
         * abbrechen:
         */
        if (pointX < centerX-radius || pointX > centerX+radius
                || pointY < centerY-radius || pointY > centerY+radius) {
            return false;
        }

        /* Nach Pythagoras: */
        double dx = pointX - centerX; // Vorzeichen egal, da quadriert wird
        double dy = pointY - centerY; // Vorzeichen egal, da quadriert wird
        if (dx*dx + dy*dy <= radius*radius) {
            return true;
        }
        else {
            return false;
        }
    }
[/EDIT]
 
Zuletzt bearbeitet:
P

pappawinni

Gast
Der TO wollte aber :
"die aktuelle position meiner Maus feststellen.
Bin ich genau auf dem Zentrum eines Kreises möchte ich ihn färben", sonst hätte ich natürlich auch noch die Umgebung der Kreisemittelpunkte geprüft, wahrscheinlich dann aber ohne eigene Klasse, sorry.
 

Marco13

Top Contributor
Nebenbei: Die Sache mit dem MouseOver-Effekt könnte man mit den angedeuteten Ellipse2D ggf. auf ein ellipse.contains(event.getPoint()) zurückführen (wenn es nicht wirklich nur für den Mittelpunkt gelten soll, dann könnte man point2D.distance(other) verwenden)
 
P

pappawinni

Gast
Also jetzt hab ich das nochmal auf ne normale Java App umgebogen und jetzt genügt auch schon das Berühren des Kreises, damit die Farbe umschlägt, was eigenlich nicht im Sinne des TO war, aber ist natürlich leicht zu ändern.

Hier also Quellcode und .jar

Java:
import java.awt.Color;

import java.awt.Graphics;
import javax.swing.JFrame;
import java.util.List;
import java.util.*;
import java.awt.event.*;
 
public class Uebung9 extends JFrame implements MouseMotionListener{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	static List<int[]> list = new ArrayList<int[]>();
    static int ledsize=16;
    static int Jframe_height;
    static int Jframe_width;
    static int lastModifiedLed;

    public Uebung9(String newTitel) {
        super.setTitle(newTitel);
        addMouseMotionListener(this);
    }
    
    public static void main(String str[]) {
        Uebung9 fenster = new Uebung9("Test");
        Jframe_height = 600;
        Jframe_width = 600;			        
        fenster.setSize(Jframe_width, Jframe_height);
    	fenster.setForeground(Color.red);
    	fenster.setBackground(Color.lightGray);
        fenster.setVisible(true);
        double winkel=0;
        int abstandx=2;
        int abstandy=4;
        double x_pos;
        double y_pos;

        x_pos = 0;
        y_pos = 0;
        list.add(new int[] {(int) x_pos,(int)y_pos,-1});
        
        for (winkel=0; winkel<360; winkel=winkel+30)
        {  
            double anglerad = Math.toRadians(winkel);
            double sinang = Math.sin(anglerad);
            double cosang = Math.cos(anglerad);
            /* Rotation y-Komponente */                    
            double vdyx= - sinang * abstandy;
            double vdyy = cosang * abstandy;
            /* Rotation x-Komponente */
            double vdxx = cosang * (abstandx+ledsize);
            double vdxy=  sinang * (abstandx+ledsize);
            
            for (int x_inc=1; x_inc< 20; x_inc++)
            {
                /* rotierte X-Komponente auf Länge bringen */
            	x_pos = x_inc * vdxx;                    	
                y_pos = x_inc * vdxy;
                
                if (x_inc%2==1)
                { 
                	/* in jedem 2ten Fall die rotierte Y-Komponente addieren */
                    x_pos += vdyx;
                	y_pos += vdyy;                            
                }
                /* Mittelpunkte ohne Verschiebung speichern */
                list.add(new int[] {(int) x_pos,(int)y_pos,-1});
            }
        }
        lastModifiedLed=-1;
                
    }
    public void paint(Graphics g){
   

        Jframe_height = this.getSize().height;
        Jframe_width = this.getSize().width;			

        int[] pinf = {0,0,0};
        if (lastModifiedLed>0){
        	pinf = list.get(lastModifiedLed);
            if (pinf[2]<0){
            	g.setColor(getBackground());
                g.fillOval(pinf[0]+Jframe_width/2-ledsize/2,
             		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
            	g.setColor(getForeground());
                g.drawOval(pinf[0]+Jframe_width/2-ledsize/2,
                		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
            }
            else
            {
            	g.setColor(getForeground());
                g.fillOval(pinf[0]+Jframe_width/2-ledsize/2,
                		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                	
            }                	
        }
        else{
            ListIterator<int[]> it = list.listIterator();
            while (it.hasNext()){
            	pinf = it.next();
                if (pinf[2]<0){
                	g.setColor(Color.red);
                    g.drawOval(pinf[0]+Jframe_width/2-ledsize/2,
                    		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                }
                else
                {
                	g.setColor(Color.red);
                    g.fillOval(pinf[0]+Jframe_width/2-ledsize/2,
                    		   pinf[1]+Jframe_height/2-ledsize/2,ledsize, ledsize);
                    	
                }
            }
          }
        }
	    public void mouseMoved(MouseEvent me)  
	     {  
             //Vergleichsposition berechnen
	          int posX = me.getX()-Jframe_width/2; 
	          int posY = me.getY()-Jframe_height/2; 
	          
             ListIterator<int[]> it = list.listIterator();
             int[] pinf; 
             int i;
             boolean bfound=false;
             double dist=0;
             while (it.hasNext()){
   	          i=it.nextIndex();
           	  pinf = it.next();
           	  dist = 2*Math.sqrt((posX-pinf[0])*(posX-pinf[0])+(posY-pinf[1])*(posY-pinf[1]));
                 if (dist<=ledsize){
               	  bfound=true;
               	  if (i==lastModifiedLed) break;
               	  it.set(new int[] {pinf[0],pinf[1],-pinf[2]});
               	  lastModifiedLed=i;
       	          repaint(); 
               	  break;
                 }                  
             }
             if (!bfound) lastModifiedLed=-1;
	     } 
	    public void mouseDragged(MouseEvent me)  
	     { 
	     }             
        
}
 

Anhänge

  • uebung9.jar
    2,7 KB · Aufrufe: 9

Marco13

Top Contributor
Wiederum mein Vorschlag...
Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CirclePainter
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().setLayout(new GridLayout(1,0));
        f.getContentPane().add(new CirclePainterPanel());
        f.setSize(1000,1000);
        f.setVisible(true);
    }
}


class CirclePainterPanel extends JPanel
{
    private final List<Shape> paintedShapes = new ArrayList<Shape>();
    private final Set<Shape> highlighedShapes = new HashSet<Shape>();
    private final Dimension previousDimension = new Dimension(-1,-1);
    
    CirclePainterPanel()
    {
        addMouseMotionListener(new MouseMotionAdapter()
        {
            @Override
            public void mouseMoved(MouseEvent e)
            {
                for (Shape shape : paintedShapes)
                {
                    if (shape.contains(e.getPoint()))
                    {
                        highlighedShapes.add(shape);
                    }
                    else
                    {
                        highlighedShapes.remove(shape);
                    }
                }
                repaint();
            }
        });
    }
    
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);
        
        if (!getSize().equals(previousDimension))
        {
            initShapes();
            previousDimension.setSize(getSize());
        }
        g.setColor(Color.RED);
        for (Shape shape : highlighedShapes)
        {
            g.fill(shape);
        }
        g.setColor(Color.BLACK);
        for (Shape shape : paintedShapes)
        {
            g.draw(shape);
        }
    }
    
    
    private void initShapes()
    {
        paintedShapes.clear();
        AffineTransform at = new AffineTransform();
        at.translate(getWidth()/2.0, getHeight()/2.0);
        for (int i=0; i<12; i++)
        {
            at.rotate(Math.toRadians(45));
            drawRay(at);
        }
    }
    
    private void drawRay(AffineTransform at)
    {
        for (int i=0; i<30; i++)
        {
            float x = (float)(Math.pow(1.1, i)-1);
            float y = (float)(Math.sin(x*0.9) * 15);
            Shape shape = new Ellipse2D.Double(x*20, y, 16, 16);
            paintedShapes.add(at.createTransformedShape(shape));
        }
    }
}
(@pappawinni: Deine Signatur bezieht sich in diesem Fall wohl auf Hausaufgaben :D )
 
P

pappawinni

Gast
Wiederum mein Vorschlag...
....

Jaaaa, ist ja wirklich schön :toll:, muss ich mir auch mal genauer anschauen.
Aber ne andere Frage.
Du hast gesagt. "statics rausschmeissen".
Jetzt hatte ich die ganze Zeit mit Applet gearbeitet, kein Problem.
Dann hab ich mehr oder minder nur den Code vom Applet in die Klasse/Methoden des TO geworfen und schon meckert er rum, dass das so nicht ginge, von wegen Referenz blabla. :bahnhof:
(Wie du siehst hab ich also auch statics drin ;( ).
Woran liegt das? Das hätte ich gern verstanden. ???:L

[EDIT]
Ich denk ich habs, hätt ich den Käse in den Konstruktor geworfen, statt in die Main, hätt es keine Probs gegeben. :oops:
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen

Neue Themen


Oben