# Thread: Drawing the sine curve

1. Member Join Date
Feb 2009
Posts
9
Rep Power
0

## 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.

Java Code:
```import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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);

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()));
}
});

}
}```  Reply With Quote

2. ## 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.  Reply With Quote

3. Member Join Date
Feb 2009
Posts
9
Rep Power
0

## Thanks for the response. Is there a simple way to fill the list with the formula y = sin(x) ?
Sorry, I'm a newbie  Reply With Quote

4. ## In a for loop.

db  Reply With Quote

5. Member Join Date
Feb 2009
Posts
9
Rep Power
0

## I made some changes to the code, but it's still not printing a curve.. or anything for that matter.

Java 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.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);

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);
}

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));
}
});

}
}```  Reply With Quote

6. ## 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:
Java 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.  Reply With Quote

7. Member Join Date
Feb 2009
Posts
9
Rep Power
0

## 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 :)  Reply With Quote

8. ## I'm very glad to hear. Thanks for the update!

For what it's worth, this is how I solved it:
Java 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);
}
}

@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.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}```
Last edited by Fubarable; 03-27-2009 at 10:08 PM.  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•