Jump to content




Recent Status Updates

View All Updates

Binpress - Cut your development time and costs in half
Photo
- - - - -

[Solved]Help Plotting A Function On A Graph

setpreferredsize

  • Please log in to reply
4 replies to this topic

#1 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 07 June 2012 - 07:00 PM

--solved, thanks to kernel coder--
I'm doing an exercise in which I have to plot a function. I have to make a graph and show the graph of f(x)=x^3. The user gets to pick the maximum value of x that is shown on the graph, and also the size of the frame. So, for example, if the user picks 300 for the size, and 2.5 for the maximum value of x the output is shown here:
Posted Image

where I need help is how to plot the actual function. How do I know figure out what x and y coordinates to use for the function?

here is my code, I've highlighted exactly where I need help:
import javax.swing.JFrame;
import java.util.Scanner;

public class PlotFunction {

	static Scanner input = new Scanner(System.in);
	
	public static void main(String[] args){
		System.out.print("Enter size of frame: ");
		int size = Integer.parseInt(input.nextLine());
		System.out.print("Enter maximum value for x: ");
		double value = input.nextDouble();
		input.nextLine();
		JFrame frame = new JFrame("Plot Function");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		PlotFunctionPanel panel = new PlotFunctionPanel(size, value);
		frame.getContentPane().add(panel);
		frame.pack();
		frame.setVisible(true);
	}
}

panel class
import javax.swing.JPanel;
import java.awt.*;

public class PlotFunctionPanel extends JPanel{

	int size;
	static double maxValue;
	
	public PlotFunctionPanel(int s, double v){
		size = s;
		maxValue = v;
		setPreferredSize(new Dimension(size, size));
	}
	
	public void paintComponent(Graphics g){
		g.drawLine(size/2, 0, size/2, size);
		g.drawLine(0, size/2, size, size/2);
		double[] tick = getTicks();
		int x = size/10, y = size/2, vA = 8;
		g.setFont(new Font("Sansserif", Font.PLAIN, size/30));
		for(int i = 0; i < 9; i++){
			g.drawLine(x, y+5, x, y-5);
			if(i != 4 && vA != 4){
				if(i > 4)
					g.drawString(tick[i]+"", x-size/40, y+size/21);
				else
					g.drawString(tick[i]+"", x-size/30, y+size/21);
				if(vA > 4)
					g.drawString(tick[vA]+"", y-size/13, x+size/60);
				else
					g.drawString(tick[vA]+"", y-size/12, x+size/60);
			}
			g.drawLine(y+5, x, y-5, x);
			x+=size/10;
			vA--;
		}
		g.setColor(Color.RED);
		//This is where I need help, I'm almost completely lost. The function has to be plotted in red
	  
	}
	
	//finds the values of the ticks on the axis e.g. -2.0, -1.5, -1.0, -0.5, 0.0, etc
	private static double[] getTicks(){
		double increment = maxValue / 5, currentTick = -1*(maxValue);
		double[] tick = new double[9];
		for(int i = 0; i < 9; i++){
			currentTick+=increment;
			tick[i] = Math.round(currentTick*100.0)/100.0;
		}
		return tick;
	}
}


thanks in advance
  • 0

#2 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 08 June 2012 - 03:04 AM

Well, following is the logic that you need in your paintComponent method after the line g.setColor(Color.RED);
Again, the logic is the same as your previous post -- we need to translate our (0,0) coordinate to (size/2, size/2).
  • First you need to a 'ratio' between your coordinate value and your screen value. As example, if the screen size is 400 and your max-value is 10, then pixels per value is 400/10 = 20 and this is the 'ratio' we need to use.
  • You need to start your x value to negative maxValue, then increment by one (or other value you want to jump).
  • You need to calculate y based on the x value and using the equation (e.g. y = x^3)
  • Multiply the x & y values by 'ratio' and after that translate the x and y relative to (size/2,size/2) coordinate
  • And, finally print that translated point on the screen.

Following is the code based on the above logic.
int min = (int)Math.floor(-maxValue);
int max = (int)Math.ceil(maxValue);
int ratio = size / (2* max);
int x1 = min, x2 = min;
int y1 = x1 * x1 * x1, y2 = x2 * x2 * x2; // here is the equation y = x^3
for(; x2 <= max; x2++){
y2 = x2 * x2 * x2;
g.drawLine(size/2 + (x1 * ratio),  size/2 - (y1 * ratio), size/2 + (x2 * ratio), size/2 - (y2 * ratio));
x1 = x2;
y1 = y2;				
}
draw_x3.PNG
  • 0

#3 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 08 June 2012 - 06:47 PM

thanks a lot, kernel coder. However, the function I'm plotting needs to be plotted in points. So what I was thinking I wanted to do is start at -maxValue and increment by 0.025, this way it will be 40 points in between every one tick, thus making it look like a more accurate line. Also, can you tell me why the ratio needs to be size/max*2? I don't understand that part exactly.

Thank you
  • 0

#4 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 08 June 2012 - 07:58 PM

Note that, you are taking two inputs -- the window size and the maximum value for x. Now you want to represent that maximum x value over right half of the window size, don't you? And the left half with the negative of that maximum value. So a unit (1) of such value is equal to window-size / (2 * maxValue) --- this is the ratio/scale between your window-size and your co-ordinate system.
  • 0

#5 Cruel Hand

Cruel Hand

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 195 posts
  • Programming Language:Java, Objective-C, Visual Basic .NET
  • Learning:C, Java, C++, Objective-C, PHP, (Visual) Basic, Python, JavaScript, Perl, Ruby, PL/SQL, Pascal, Assembly, Haskell

Posted 09 June 2012 - 11:43 AM

thanks, kernelcoder. I understand now. I took some of what you gave me and revised it, and got this:
double min = (-maxValue), max = maxValue, ratio = size/(max*2), fx;
        for(;min<=max;min+=0.025){
            //preventing round-off error
            min=Math.round(min*1000.0)/1000.0;
            fx=Math.round((min*min*min)*1000.0)/1000.0;
            g.drawLine((int)(size/2+(ratio*min)), (int)(size/2-(ratio*fx)),
                    (int)(size/2+(ratio*min)), (int)(size/2-(ratio*fx)));
        }

which gives this as the output:
Posted Image
  • 0





Also tagged with one or more of these keywords: setpreferredsize

Powered by binpress