Results 1 to 8 of 8
Thread: Drawing the sine curve
- 03-11-2009, 07:25 PM #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.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())); } }); } }
-
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, 08:03 PM #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
- 03-11-2009, 08:05 PM #4
In a for loop.
db
- 03-12-2009, 05:01 PM #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.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)); } }); } }
-
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:
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.Java Code:public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createGUI(); } }); }
- 03-26-2009, 04:58 PM #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 :)
-
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); 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); } }Last edited by Fubarable; 03-27-2009 at 09:08 PM.
Similar Threads
-
Java Learning Curve
By mwildam in forum New To JavaReplies: 13Last Post: 10-17-2008, 11:09 AM -
Demonstration of drawing points. It draws a sine wave
By Java Tip in forum SWTReplies: 0Last Post: 06-28-2008, 09:25 PM -
How to draw text along a curve
By Java Tip in forum java.awtReplies: 0Last Post: 06-25-2008, 10:31 AM -
How to draw Curve using QuadCurve2D
By Java Tip in forum java.awtReplies: 0Last Post: 06-23-2008, 11:20 PM -
How to Draw Curve with mouse
By Java Tip in forum java.awtReplies: 0Last Post: 06-23-2008, 11:20 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks