Hi,
I am jahan, i just started java applets and i was trying to draw a graph. The idea i am using is based on drawLine(xmin,ymin,xmax,ymax). I wanted to get a graph for sinx which is proving to be difficult. i used following syntax to implement my idea:

import java.awt.*;
import java.applet.*;

public class graphic extends Applet {
    Button button1;
    public void init() {
    }

    public void paint(Graphics g) {
        Button button1 = new Button("Plot");
        add(button1);
        g.setColor(Color.blue);
        g.drawLine(600,0,600,1000);    // x-axis
        g.drawLine(0,350,1400,350);// y-axis

       for (int i=0;i<=1000;i++)
       {
        g.drawLine(i,(int)Math.sin(i),i,(int)Math.sin(i));//Suppose to give me a graph 
                //even tho at random location        
}
    }
}

But result of this code is just a straight line along x-axis , the only thing which comes to my mind is about using cast in here when i did (int)Math.sinx, it is giving me strange value. It cud be because all the value below 0.5 are taken as 0 and above 0.5 are taken as 1.So if anyone can suggest me a way to solve this problem.

Recommended Answers

All 13 Replies

Keep in mind what Graphics.drawLine does.

You're trying to draw a point from i to i, and Math.sin(i) to Math.sin(i) so you're going to get something like a line due to the fact that your points aren't varying from x1 to x2 and y1 to y2.

Try g.drawLine(i,(int)Math.sin(i),i + 2,(int)Math.sin(i))));

Keep in mind what Graphics.drawLine does.

You're trying to draw a point from i to i, and Math.sin(i) to Math.sin(i) so you're going to get something like a line due to the fact that your points aren't varying from x1 to x2 and y1 to y2.

Try g.drawLine(i,(int)Math.sin(i),i + 2,(int)Math.sin(i))));

sorry for quoting myself, but instead of Math.sin(i) use Math.sin(i + ((2 * i)/(2 * Math.PI))) in the last argument.

it might be Math.pi or Math.Pi for the pi constant... bah!

I'm not anywhere near a java compiler atm >_>

Now that I think about it, you probably don't want to simply use Math.sin(i) in your statement.

This means that you're going to go around the circle VERY fast as i increments. Your wavelength will most likely be small unless you use some kind of scalar that multiplies by the sin function (like 50 or so).

If anything, think about how many sin cycles you want in 1000 increments.

Let's say you want 4 cycles (where a cycle is simply 360 degrees (or 2pi radians) reached). Then you'd have to find out when your number reaches a cycle and multiply by that value.

final double CYCLE = 4
final double MAX = 1000

math.sin( ((i + 2)* Math.pi * CYCLE) / ( MAX) ) for the second y arg, and most likely
math.sin(((i) * Math.pi * CYCLE)/ MAX) for the first y arg.

Hi guys, drawLine() doesn't require the points to vary. In fact drawLine(10,10,10,10) would simply result in a point being drawn.

It's Math.PI because all constants, as per the Java convention, are in uppercase. He isn't using degrees though so there isn't a need to convert between degrees and radians; Math.sin(x) where x is an angle measured in radians. The conversion is degrees * PI/180 btw.

He isn't drawing a circle and his approach is almost correct...

What you need to remember Jahan, is that sin graphs have an amplitude of 1 unit. That is, your y value is going to range between -1 and 1 (at least in this case). Since you're dealing with a continuous function, your (int) conversion is going to give you values of either -1, 0 or 1 and this is not what you want. I suggest multiply the double value you get from the sin method with some constant before you convert the value to int. I hope this makes sense? This constant should be used to scale your x value of the Cartesian plane to pixels so perhaps 1 x unit is 10 pixels.

Moreover, your graph isn't going to be drawn on the axises you created because your (x, y) pairs in the drawLine() method don't match the values of your axises. It's not a difficult thing to do, but it does require you to think of the differences between a Cartesian plane and the pixel co-ordinate system you're using on your computer.

Hi guys, drawLine() doesn't require the points to vary. In fact drawLine(10,10,10,10) would simply result in a point being drawn.

It's Math.PI because all constants, as per the Java convention, are in uppercase. He isn't using degrees though so there isn't a need to convert between degrees and radians; Math.sin(x) where x is an angle measured in radians. The conversion is degrees * PI/180 btw.

He isn't drawing a circle and his approach is almost correct...

What you need to remember Jahan, is that sin graphs have an amplitude of 1 unit. That is, your y value is going to range between -1 and 1 (at least in this case). Since you're dealing with a continuous function, your (int) conversion is going to give you values of either -1, 0 or 1 and this is not what you want. I suggest multiply the double value you get from the sin method with some constant before you convert the value to int. I hope this makes sense? This constant should be used to scale your x value of the Cartesian plane to pixels so perhaps 1 x unit is 10 pixels.

Moreover, your graph isn't going to be drawn on the axises you created because your (x, y) pairs in the drawLine() method don't match the values of your axises. It's not a difficult thing to do, but it does require you to think of the differences between a Cartesian plane and the pixel co-ordinate system you're using on your computer.

There is no rate of change in his function as i increments. Basically the graph isn't dependent on i, so he ends up with a constant graph, or a straight line.

for example

(y2 - y1) / (x2 - x1) = 0 which is a constant and he would definitely get a straight line from whatever a-to-b interval.

Unfortunately there is a serious loss of precision when using

(int)Math.sin(i) because it will almost always evaluate to zero since the only time Math.sin(i) is a true integer is when it is -1 or 1 which is its peak. As I increases you will skip PI or 2PI using integer incrementing in Math.sin(i) which means you will skip the maximum and minimum values that bring Math.sin(i) to -1 or 1 and immediately generate a graph that looks much like it does not vary (you'll get numbers between -1 and 1 and cast them as an int in which an int cant hold the information and be immediately cast to the next best thing - zero).

You have a few "bumps" in your graph most likely because you reached a multiple of PI.

Also the logic I provided wasn't for a circle. It was to make the y and x vary enough to generate a sin graph, however there is no variance and there is no way to generate a precise enough number before casting it into an int to satisfy the method.... unless he can pull off something like--

(int)(10 * Math.sin(i))

--to cast the value into an int after it has been increased past 1 for better results.

g.drawLine(i,(int)(50 * Math.sin(((i)* 2 * Math.PI * CYCLE) / ( MAX))),(i+1),(int)(50 * Math.sin(((i+1)* 2 * Math.PI * CYCLE) / ( MAX))));

where CYCLE is a final int 4 and MAX is final int 1000

This actually worked.

By the way, it might not be a good idea to add a button in paint(Graphics g) method, because each time you resize the applet paint is called (which makes sense, because it needs to redraw components when it has been resized).

Yes, you definitely do not want to be adding components in paint().

Thanks for your replies , i really wasn't expecting so many replies for my simple question.Because of your explanation in detail i understood it properly.Mathematically Alex is 100% right , because it really gives me a gradient of zero which is literally a straight line. I have changed my code and it gives me a sine curve but , it sticks to the top of the window but i hope that can be figured out . Once again thanks for the help and thanks for supporting the idea that g.drawLine(i,i,i,i) represents a point .Hopefully i ill be posting the code when its all done :)

Thanks for your replies , i really wasn't expecting so many replies for my simple question.Because of your explanation in detail i understood it properly.Mathematically Alex is 100% right , because it really gives me a gradient of zero which is literally a straight line. I have changed my code and it gives me a sine curve but , it sticks to the top of the window but i hope that can be figured out . Once again thanks for the help and thanks for supporting the idea that g.drawLine(i,i,i,i) represents a point .Hopefully i ill be posting the code when its all done :)

I wish I could help you with using more of the Graphics class's functions but unfortunately I truly HATE using Graphics from getGraphics in containers. I wouldn't be able to help you with setting the location of your Graphics object.

I personally prefer using GObjects, GCompounds, GLines that work on GCanvases.

The only method I have an issue with understanding is the move method in most GObject classes. I'm almost certain that it fires a thread that continuously offsets the object but i could be wrong.

import java.awt.*;
import java.applet.*;

public class graphic extends Applet {
    Button button1;
    public void init() {
    }

    public void paint(Graphics g) {

        int CYCLE=4;
        int MAX = 1000;
        int x1=0;
        int x2=0;
        g.setColor(Color.red);//color for axes
        g.drawLine(0,150,700,150);//x-axis
        g.drawLine(240,0,240,500);//y-axis
        g.drawString("X-Axis", 430,140);//Label for x-axis
        g.drawString("Y-Axis",200,270);//Label for y-axis
        g.setColor(Color.blue);//color for the sin curve

         for (int i=-130;i<=368;i++)
       {      
        try 
            {
           Thread.sleep(10); // 10 millisecond delay 
            } 
            catch(InterruptedException e)
            {
           e.printStackTrace();
            } 

        x1 = (int)(100 * Math.sin(((i)*2*Math.PI*CYCLE)/(MAX)));
        x2 = (int)(100 * Math.sin(((i+1)*2*Math.PI*CYCLE)/(MAX)));      
        g.drawLine(i+121,x1+138,(i+1)+121,x2+138);
       }
        g.setFont(new Font("Times New Roman",Font.BOLD,15));
        g.drawString("IT WORKS ; )",100,50);    }   
}
//Here is the code

import java.awt.*;
import java.applet.*;

public class graphic extends Applet {
Button button1;
public void init() {
}

public void paint(Graphics g) {

int CYCLE=4;
int MAX = 1000;
int x1=0;
int x2=0;
g.setColor(Color.red);//color for axes
g.drawLine(0,150,700,150);//x-axis
g.drawLine(240,0,240,500);//y-axis
g.drawString("X-Axis", 430,140);//Label for x-axis
g.drawString("Y-Axis",200,270);//Label for y-axis
g.setColor(Color.blue);//color for the sin curve

for (int i=-130;i<=368;i++)
{
try
{
Thread.sleep(10); // 10 millisecond delay
}
catch(InterruptedException e)
{
e.printStackTrace();
}

x1 = (int)(100 * Math.sin(((i)*2*Math.PI*CYCLE)/(MAX)));
x2 = (int)(100 * Math.sin(((i+1)*2*Math.PI*CYCLE)/(MAX)));
g.drawLine(i+121,x1+138,(i+1)+121,x2+138);
}
g.setFont(new Font("Times New Roman",Font.BOLD,15));
g.drawString("IT WORKS ; )",100,50); }
}
//Here is the code

import java.awt.*;
import java.applet.*;

public class graphic extends Applet {
	Button button1;
	public void init() {
	}

	public void paint(Graphics g) {
     
        int CYCLE=4;
        int MAX = 1000;
        int WEIGHT = 100;
		int x1=0;
		int x2=0;
		g.setColor(Color.red);//color for axes
		g.drawLine(0,150,700,150);//x-axis
        g.drawLine(240,0,240,500);//y-axis
        g.drawString("X-Axis", 430,140);//Label for x-axis
        g.drawString("Y-Axis",200,270);//Label for y-axis
        g.setColor(Color.blue);//color for the sin curve
        
         for (int i=-130;i<=368;i++)
       {  	  
       	try 
            {
           Thread.sleep(10); // 10 millisecond delay 
            } 
            catch(InterruptedException e)
            {
           e.printStackTrace();
            } 
	
       	x1 = (int)(WEIGHT * Math.sin(((i)*2*Math.PI*CYCLE)/(MAX)));
       	x2 = (int)(WEIGHT * Math.sin(((i+1)*2*Math.PI*CYCLE)/(MAX)));  	
       	g.drawLine(i+121,x1+138,(i+1)+121,x2+138);
       }
        g.setFont(new Font("Times New Roman",Font.BOLD,15));
        g.drawString("IT WORKS ; )",100,50);	}	
}
//Here is the code

Keep in mind that the MAX is really the maximum difference between the min-x and max-x values.

For example, if you can go from -100 to 100 in your graph, MAX should be the difference of the two, resulting in MAX = 200

Edit: Added an int named WEIGHT that controls the peak and valley of your sin graph. The greater the WEIGHT the deeper and steeper your waves, the lower the WEIGHT the more subtle your graph will be.

commented: Good work :) +2

Alex said:

There is no rate of change in his function as i increments. Basically the graph isn't dependent on i, so he ends up with a constant graph, or a straight line.

Well that's not exactly true; the gradient (i.e. rate of change) of a Sin curve depends on the input. Though I did misread the part about the circle, my bad :icon_redface:

Good work Alex :icon_wink: Though because of the nature of a Sin graph, one did not have to consider the changed between graphics and the Cartesian plane. On the screen y increases as we move down, however, on the Cartesian plane, y increase as we move up. Something to consider if ever you needed to draw, say a straight line.

So perhaps mark this post as Solved :icon_cool:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.