Sinus und Kosinus Graph

Hm, Du hast es doch schon so gut wie. Ändere mal rot gegen grün:

Code:
        int endX = endx;
        double iter = st.x;
        GeneralPath line = new GeneralPath();
        line.moveTo((float)st.x, (float)st.y);
        while (iter < endX) {
          iter = iter + 0.1;
          line.lineTo((float)iter, (float)Math.sin(iter));
        }
        while (iter *10< endX) {
          iter = iter + 0.1;
          line.lineTo(iter*10, 20*Math.sin(iter));
        }

        BasicStroke stroke1 = new BasicStroke(strokeWidth);
        g.setStroke(stroke1);
        g.draw(line);
 
Mist, irgendwie t das bei mir nicht...
Momentan rufe ich bei Mousedragged folgende sache auf:

Code:
Line2D.Float line = new Line2D.Float( (float) st.x,
                                             (float) st.y,
                                             (float) endx,
                                             (float) endy);


        path = new GeneralPath(line);
        BasicStroke stroke1 = new BasicStroke(strokeWidth);
        g.setStroke(stroke1);
        g.draw(path);

Diese malt meine Linie super. Problem ist wohl auch dass ich ein 2D-Objekt nutze.
Wenn ich deine Zeilen einfüge, als:

Code:
/*Line2D.Float line = new Line2D.Float( (float) st.x,
                                             (float) st.y,
                                             (float) endx,
                                             (float) endy);*/


        int endX = endx;
        double iter = st.x;
        GeneralPath line = new GeneralPath();
        line.moveTo((float)st.x, (float)st.y);
        while (iter < endX) {
          iter = iter + 0.1;
          line.lineTo((float)iter, (float)Math.sin(iter));
        }
        while (iter *10< endX) {
          iter = iter + 0.1;
          line.lineTo((float)iter*10, (float)(20*Math.sin(iter)));
        }

        BasicStroke stroke1 = new BasicStroke(strokeWidth);
        g.setStroke(stroke1);
        g.draw(line);


        /*path = new GeneralPath(line);
        BasicStroke stroke1 = new BasicStroke(strokeWidth);
        g.setStroke(stroke1);
        g.draw(path);*/

wird nur folgendes gezeichnet. Der unterste Punkt der senkrechten Linie war mein Startpunkt und ich habe die Maus dann nach rechts oben bewegt.
Weißt du nochmal Rat?
Danke
 
Mist irgendwie kam die Grafik nicht mit. Es wird quasi eine senkrechte Linie gezeichnet u. dann eine gestrichelte am oberen Rand des Frames
 
Moin!
1. du musst deinen Rotationswinkel messen, d.h. Winkel zwischen der x- Achse und der "neuen" x-Achse.
2. Wie gehabt, Werte berechen
3. Die Werte mittels einer RotationsMatrix neu berechen
4. Zeichen.

Als Beispiel mal für den Winkel 45 Grad bzw. PI/4

Code:
public void paint(Graphics g){
    super.paint(g);
    float startx = 1;
    float starty = 1;
    float endx = 50;
    float endy = 50;
    float iter =0;
    GeneralPath line = new GeneralPath();
    line.moveTo(1+30,1+30);
    AffineTransform trans = AffineTransform.getRotateInstance(Math.PI/4,30,30);
    
    while(startx< endx){
        double value = Math.sin(startx);
        Point src = new Point((int)startx+30,((int)(starty+30+Math.sin(value)*20)));
        Point dst = new Point();
        trans.transform(src,dst);
        
        line.lineTo(dst.x,dst.y);
        startx = startx+0.1f;
        
    }
    ((Graphics2D)(g)).draw(line);


*grüssle*
MeinerEiner
 
Moin,
also wenn ich das jetzt richtig verstanden habe, könnte ich also auch einfach einen Linie interaktiv zeichnen und sobald ich die Maus loslasse berechne ich den gezeichneten Winkel zwischen Startpunkt und Endpunkt und erstelle eine Sinuskurve über diese Distanz...

Müsste doch gehen oder?
 
Rischtisch!
Viel ändern musst du dafür an meinen Code ja nicht.. Habe den Winkel und den Endpunkt fest eingetragen.. Ist ja nun kein Problem mehr, das dynamisch zu gestalten..

*grüssle*
MeinerEiner
 
Ich hab da mal was zusammengeschraubt. Experimentier doch mal an diesem Panel rum.
1. Klick Startpunkt 2. Klick Endpunkt. Mausrad (+Shift) skaliert.

Code:
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class SinusPanel extends JPanel {
	static final long serialVersionUID = 01L;
	
	private ClickListener myMouseListener;
	private GeneralPath line;
	private int scaleY, scaleX, width, height;
	private int startX, startY, endX, endY;
	
	public SinusPanel() {
		super();
		line = new GeneralPath();
		myMouseListener = new ClickListener();
		this.addMouseListener(myMouseListener);
		this.addMouseWheelListener(myMouseListener);
		endX = 0;
		endY = 0;
		startX = 0;
		startY = 0;
		scaleY = 20;
		scaleX = 10;
		width = 300;
		height = 300;
		this.setSize(width,height);
		this.setBackground(new Color(0,150,0));
	}
	
	private class ClickListener implements MouseListener, MouseWheelListener {

		private boolean startPoint = true;
		
		public void mousePressed(MouseEvent e) {}		
		public void mouseExited(MouseEvent e) {}		
		public void mouseClicked(MouseEvent e) {
			if(e.getButton() == MouseEvent.BUTTON1) {
				if(startPoint) {
					startX = e.getPoint().x;
					startY = e.getPoint().y;
					startPoint = !startPoint;
					endX = 0;
					endY = 0;
				} else {
					endX = e.getPoint().x;
					endY = e.getPoint().y;
					startPoint = !startPoint;					
				}
				repaint();
			} 
		}		
		public void mouseEntered(MouseEvent e) {}		
		public void mouseReleased(MouseEvent e) {}	
		public void mouseWheelMoved(MouseWheelEvent e) {
			if((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK)==MouseEvent.SHIFT_DOWN_MASK)
			{
				if(e.getWheelRotation() > 0) {
						scaleY += 10;
						repaint();
					} else {
						scaleY -= 10;
						repaint();
					}
			} else {
				if(e.getWheelRotation() > 0) {
					scaleX += 1;
					repaint();
				} else {
					scaleX -= 1;
					repaint();
				}
				
			}
		}
	};
	
	public void paint(Graphics g) {
		super.paint(g);
        double iter = 0.0;
        int tmpX, tmpY;

        // Einheitsvektor erstellen und Winkel zur X-Achse berechnen
        double eX, eY;
        eX = endX - startX;
        eY = endY - startY;
        double graphLength = vectorLength(eX, eY);
        eX = eX / graphLength;
        eY = eY / graphLength;
        double arc = vectorArc(1.0, 0.0, eX, eY);
        
        g.drawOval(startX-3, startY-3, 6,6);
        if(endX != 0 || endY != 0)
        {      
	        g.drawOval(endX-3, endY-3, 6,6);
	
	        // Graph zeichnen
	        line.reset();
	        line.moveTo(startX, startY);
	        if(scaleX > 0)
	        while (iter*scaleX < graphLength) {
	          iter = iter + 0.1;
	          tmpX = (int) Math.round(iter*scaleX+startX);
	          tmpY = (int) Math.round(scaleY*Math.sin(iter)+startY);
	          line.lineTo(tmpX, tmpY);
	        }
	        AffineTransform rotation = AffineTransform.getRotateInstance(arc, startX, startY);
	        line.transform(rotation);
	        ((Graphics2D) g).draw(line);		
        }
	}
	
	private double vectorLength(double x, double y) {
		double tmpD = Math.sqrt(Math.pow(x, 2.0) + Math.pow(y, 2.0));
		System.out.println("Length:"+tmpD);
		return tmpD;
	}
	
	private double vectorArc(double x1, double y1, double x2, double y2) {
		double tmpD = 0.0;
		if(y1-y2 > 0) {
			tmpD = (-1.0) * Math.acos((x1*x2+y1*y2)/vectorLength(x1,y1)*vectorLength(x2,y2));
		} else {
			tmpD = Math.acos((x1*x2+y1*y2)/vectorLength(x1,y1)*vectorLength(x2,y2));
		}
		System.out.println("Arc:"+tmpD);
		return tmpD;
	}

}
 
Zuletzt bearbeitet:
Super, ich teste jetzt mal rum und melde mich falls noch Fragen sind...
Vielen Dank schon jetzt einmal.
 
Hallo nochmal.
@inter: supergeniale Sache. Hab es endlich geblickt :) Nochmals tausend Dank.

Kann man das auch so einstellen, dass die linie immer im Endpunkt endet und nicht etwas drüber oder drunter?

Schönes WE euch allen
 
Kann man das auch so einstellen, dass die linie immer im Endpunkt endet und nicht etwas drüber oder drunter?

Naja, die Sinus-Funktion hat die Periode 2*pi. D.h. sie ist bei allen Vielfachen von pi gleich 0. Da Du am Ende Deines Graphen wieder bei 0 ankommen willst, musst Du also die Länge des Graphen entsprechend anpassen. Das widerspricht allerdings Deiner Absicht, den Graphen in der Länge zu malen, die Du mit der Maus klickst. Allerdings kannst Du die Skalierung auf der X-Achse so ändern, dass die gegebene Länge immer ein Vielfaches von pi darstellt.

Ändere die While-Schleife so:

Code:
	        while (iter < scaleX) {
	          iter = iter + 0.1;
	          tmpX = (int) Math.round((iter*graphLength/scaleX)+startX);
	          tmpY = (int) Math.round(scaleY*Math.sin(iter)+startY);
	          line.lineTo(tmpX, tmpY);
	        }

Außerdem muss scaleX immer ein Vielfaches von Pi sein. Also ändere den Konstruktor und den Listener:

Code:
// Im Konstruktor
scaleX = Math.PI;

// Im Listener
if(e.getWheelRotation() > 0) {
	scaleX += Math.PI;
	repaint();
} else {
	scaleX -= Math.PI;
	repaint();
}
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück