# Drawing the sine curve

• 03-11-2009, 08:25 PM
bumblyb33
Drawing the sine curve
Hi

I need help on drawing a sine curve. To get started, I'm trying to draw the first peak.. but it's printing a straight line. So how do I actually get it to curve?! Here is the code I'm working on, any help greatly appreciated.

Code:

```import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.QuadCurve2D; import java.util.Vector; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; class Tester extends JFrame {                           public static void main(String[] args) {             final JFrame f = new JFrame("My frame");             f.setSize(600, 400);             f.setVisible(true);                         f.add(new JComponent(){                                         public void paintComponent(Graphics g)                     {                             g.drawLine(0,0,0,f.getHeight());                             g.drawLine(0, f.getHeight()/2, f.getWidth(), f.getHeight()/2);                             Graphics2D g2 = (Graphics2D) g;                             g2.drawString("1", 10,25);                             g2.drawString("-1",10,f.getHeight()-50);                             g2.draw(new QuadCurve2D.Double(50, f.getHeight()/2, Math.sin(Math.PI),Math.sin(Math.PI), 100, f.getHeight()));                     }             });                       } }```
• 03-11-2009, 08:41 PM
Fubarable
One way to do this is to create a collection of Points such as an ArrayList<Point>, to fill the list based on your math formula, and then to render the curve in paintComponent by iterationg through the points in the pointList and using these points to create lines connecting one point with its neighbor.
• 03-11-2009, 09:03 PM
bumblyb33
Thanks for the response. Is there a simple way to fill the list with the formula y = sin(x) ?
Sorry, I'm a newbie
• 03-11-2009, 09:05 PM
DarrylBurke
In a for loop.

db
• 03-12-2009, 06:01 PM
bumblyb33
I made some changes to the code, but it's still not printing a curve.. or anything for that matter.

Code:

```import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.QuadCurve2D; import java.util.ArrayList; import java.util.Vector; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; class Tester extends JFrame {                           public static void main(String[] args) {                                 final ArrayList<Point> list = new ArrayList<Point>();             final JFrame f = new JFrame("My frame");             f.setSize(600, 400);             f.setVisible(true);                         f.add(new JComponent(){                                         public void paintComponent(Graphics g)                     {                             g.drawLine(0,0,0,f.getHeight());                             g.drawLine(0, f.getHeight()/2, f.getWidth(), f.getHeight()/2);                             Graphics2D g2 = (Graphics2D) g;                             g2.drawString("1", 10,25);                             g2.drawString("-1",10,f.getHeight()-50);                             for(int i=0; i<100; i++)                             {                                     Point p = new Point(i, (int)Math.sin(i) + f.getHeight()/2);                                     list.add(p);                             }                                                         for(int i=0; i<list.size()-1; i++)                             {                                     Point p1 = (Point)list.get(i);                                     Point p2 = (Point)list.get(i+1);                                     g2.drawLine((int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY());                             }                             //g2.draw(new QuadCurve2D.Double(0, f.getHeight()/2, 5, f.getHeight(), 100, f.getHeight()/2));                     }             });                       } }```
• 03-12-2009, 07:00 PM
Fubarable
1) Your class should not extend JFrame as it is not using this JFrame but instead is using another one.

2) Create an ArrayList of Point2D.

3) Create your data points outside of the paintComponent method. You don't want to slow down painting if it can be helped. You will fill the List with Point2D.Double objects.

4) Your math is wrong. Think of what the math should be on paper before committing it to code.

5) Within the paintComponent method, you'll want to multiply the x and y doubles from the list by an xMultiplier and a yMultiplier and then cast the result to int. These multipliers will be partly based on the JComponent's width and height. Again, you should figure out the values on paper before committing it to code. Myself, when I did this program I used constants such as ITER_MAX - the number of data points I wanted and CYCLE - the number of sine cycles I wanted to display. I also used Math.PI in my calculations. I also changed my y values to 1 - yValue before applying the yMultiplier so that the Y value was visible on the screen (otherwise the mid line of the curve was at y == 0 which means I only saw 1/2 of the sine curve).

6) Call all the code currently held in your main method on the EDT. What I did was change the main method to this:
Code:

```  public static void main(String[] args)   {     SwingUtilities.invokeLater(new Runnable()     {       public void run()       {         createGUI();       }     });   }```
and then called all the stuff that was in the main method instead in the createGUI method. This will help with thread safety, but also will slow down creation of the GUI a little to allow the data points to be plotted first.
• 03-26-2009, 05:58 PM
bumblyb33
Sorry I've taken a while to reply, I've been away.

Thanks for the advice you've given me, it's been a great help. Problem solved :)
• 03-26-2009, 11:29 PM
Fubarable
I'm very glad to hear. Thanks for the update!

For what it's worth, this is how I solved it:
Code:

```import java.awt.BasicStroke; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class SineCurve extends JPanel {   public static final int MAX_POINTS = 200;   public static final int CYCLES = 1;   private static final float STROKE_WIDTH = 8.0f;   private static final Dimension APP_SIZE = new Dimension(800, 600);   private List<Point2D> points = new ArrayList<Point2D>();     public SineCurve()   {     double phaseMultiplier = 2 * Math.PI * CYCLES / MAX_POINTS;     for (int i = 0; i < MAX_POINTS; i++)     {       double cycleX = i * phaseMultiplier;       double sineResult = Math.sin(cycleX);       points.add(new Point2D.Double(cycleX, sineResult));     }   }     @Override   protected void paintComponent(Graphics g)   {     super.paintComponent(g);     int width = getWidth();     int height = getHeight();     g.drawLine(0, height/2, width, height/2);     Graphics2D g2 = (Graphics2D)g;     g2.setStroke(new BasicStroke(         STROKE_WIDTH,         BasicStroke.CAP_ROUND,         BasicStroke.JOIN_ROUND));     g2.setRenderingHint(         RenderingHints.KEY_ANTIALIASING,         RenderingHints.VALUE_ANTIALIAS_ON);     if (points.size() > 1)     {       double xMultiplier = width/(2 * Math.PI * CYCLES);       double yMultiplier = height / 2.0;       Point2D prevPoint = null;       for (Point2D point : points)       {         if (prevPoint != null)         {           int x1 = (int) (xMultiplier * prevPoint.getX());           int y1 = (int) (yMultiplier * (1.0 - prevPoint.getY()));           int x2 = (int) (xMultiplier * point.getX());           int y2 = (int) (yMultiplier * (1.0 - point.getY()));           g2.drawLine(x1, y1, x2, y2);         }         prevPoint = point;       }     }   }     public static void main(String[] args)   {     SwingUtilities.invokeLater(new Runnable()     {       public void run()       {         createAndShowGUI();       }     });   }   private static void createAndShowGUI()   {     SineCurve sineCurve = new SineCurve();     sineCurve.setPreferredSize(APP_SIZE);         JFrame frame = new JFrame();     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     frame.getContentPane().add(sineCurve);     frame.pack();     frame.setLocationRelativeTo(null);     frame.setVisible(true);   } }```