/* 
 * CurveComponent.java
 *
 * (C) Copyright 2007, Morten Rhiger
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * March 14, 2007, Morten Rhiger (mir@ruc.dk)
 */

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JComponent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

public class CurveComponent extends JComponent {
  
    private double f(double x) {
	// compute f(x) here
	return Math.sin(x * x);
    }       
	

    public void paintComponent(Graphics g) {
	Graphics2D g2 = (Graphics2D) g;

	int width  = getWidth();
	int height = getHeight();


	// Where to put the origo of the coordinate system?

	double center_x = width / 3.0;
	double center_y = height / 2.0;


	// How many pixels per unit in the coordinate system?

	double resolution_x = 50.0;
	double resolution_y = 50.0;

	
	// Clear window

	g2.setBackground(Color.WHITE);
	g2.clearRect(0, 0, width, height);


	// Draw coordinate system

	g2.setColor(Color.LIGHT_GRAY); // or Color.RED

	g2.draw(new Line2D.Double(0, center_y, width, center_y));
	g2.draw(new Line2D.Double(center_x, 0, center_x, height));


	// draw ticks

	java.text.DecimalFormat fmt = 
	    new java.text.DecimalFormat("####.00");

	int mark_x = 0;
	for (double x = center_x; x >= 0; x -= resolution_x) {
	    if (mark_x != 0) {
		g2.draw(new Line2D.Double(x, center_y - 5, x, center_y + 5));
		g2.drawString("" + mark_x, (float) x, (float) (center_y + 15));
	    }
	    mark_x--;
	}

	mark_x = 0;
	for (double x = center_x; x < width; x += resolution_x) {
	    if (mark_x != 0) {
		g2.draw(new Line2D.Double(x, center_y - 5, x, center_y + 5));
		g2.drawString("" + mark_x, (float) x, (float) (center_y + 15));
	    }
	    mark_x++;
	}

	int mark_y = 0;
	for (double y = center_y; y >= 0; y -= resolution_y) {
	    if (mark_y != 0) {
		g2.draw(new Line2D.Double(center_x - 5, y, center_x + 5, y));
		g2.drawString("" + mark_y,
			      (float) (center_x + 15), (float) y + 4.0F);
	    }
	    mark_y++;
	}

	mark_y = 0;
	for (double y = center_y; y < width; y += resolution_y) {
	    if (mark_y != 0) {
		g2.draw(new Line2D.Double(center_x - 5, y, center_x + 5, y));
		g2.drawString("" + mark_y, 
			      (float) (center_x + 15), (float) y + 4.0F);
	    }
	    mark_y--;
	}	    


	// Draw legend

	g2.drawString("sin(x * x)", 20.0F, 20.0F);
	g2.drawString("x = ["
		      + fmt.format((0 - center_x) / resolution_x) 
		      + "; "
		      + fmt.format((width - center_x) / resolution_x)
		      + "]",
		      20.0F, 35.0F);
	g2.drawString("y = ["
		      + fmt.format((0 - center_y) / resolution_y) 
		      + "; "
		      + fmt.format((height - center_y) / resolution_y)
		      + "]",
		      20.0F, 50.0F);


	// Draw curve

	g2.setColor(Color.BLACK);

	Point2D.Double left = null;

	for (double sx = 0; sx < width; sx += 1) {

	    // Convert screen x coordinate sx (in pixels) to the
	    // coordinate system of the curve:

	    double x = (sx - center_x) / resolution_x;

	    // Compute y coordinate

	    double y = f(x);

	    // Convert y in the coordinate system of the curve to
	    // screen coordinates (remember to negate the y value):
	    
	    double sy = center_y - y * resolution_y;

	    // Construct right-most point. Then draw from left-most
	    // point to right-most point:

	    Point2D.Double right = new Point2D.Double(sx, sy);

	    if (left != null) 
		g2.draw(new Line2D.Double(left, right));

	    left = right;
	}
    }

    public static void main(String[] args) {
	JFrame frame = new JFrame();

	frame.setSize(400, 400);
	frame.setTitle("Curve");
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	frame.add(new CurveComponent());

	frame.setVisible(true);

	
    }

}

