CS335 (Fall 2008)
Solution of Homework 5 (20 points)
Due: 10/30/08


1)
///////////////////////////////////////
//
//  File: bezier.java
//
///////////////////////////////////////

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class bezier extends Applet {
private int count;
private int px[], py[];
private Color c1, c2;
private final int no_points=20;
private int cx, cy, nx, ny;

public void init ( ){
	DetailHandler myDetailHandler = new DetailHandler( this );
	px = new int[ 4 ];
	py = new int[ 4 ];
	addMouseListener( myDetailHandler );
	addMouseMotionListener( myDetailHandler );
}

public void paint( Graphics g ){
    if ( count >= 4 ){
        for (int i=0; i < count; i++) { // draw control points
            g.drawLine( px[ i ]-3, py[ i ], px[ i ]+3, py[ i ]);
            g.drawLine( px[ i ], py[ i ]-3, px[ i ], py[ i ]+3 );
        }

        g.setColor( Color.red );
        setForeground( c1 );
        for (int i=0; i < count-1; i++) { // draw control polygon
            g.drawLine( px[ i ], py[ i ], px[ i+1 ], py[ i+1 ]);
        }

        cx = px[ 0 ];
        cy = py[ 0 ];

        for (int i=1; i < no_points; i++ ) { // draw the curve
            nx = nextPoint( px, i, no_points );
            ny = nextPoint( py, i, no_points );
            g.drawLine( cx, cy, nx, ny );
            cx = nx; cy = ny;
        }
        g.drawString( "To drag a control point, click and hold", 10, 20);
        g.drawString( "button pressed at that point, move cursor", 10, 35);
        g.drawString( "to desired location, then release button", 10, 50);
    }
    else { // prompt the user
        g.drawString( "Click mouse to input control point " + count, 10, 20 );
        if ( count > 0 )
            for (int i=0; i < count; i++) { // show the control points
                g.drawLine( px[ i ]-3, py[ i ], px[ i ]+3, py[ i ]);
                g.drawLine( px[ i ], py[ i ]-3, px[ i ], py[ i ]+3 );
            }
    }
}


public int getCount() { 
	return count; 
}

public void update( MouseEvent e ){
    if (count<4) {
        count += 1;
        px[ count - 1 ] = e.getX();
        py[ count - 1 ] = e.getY();
    }
}


public void drawControlPoint() { 
    repaint(); 
}


public int nextPoint( int a[], int j, int k ){
    double v, t;
    t = (double) j/k ;
    v = (double) (1-t)*(1-t)*(1-t)*a[0] + 3*(1-t)*(1-t)*t*a[1]
	              +3*(1-t)*t*t*a[2] + t*t*t*a[3];
    return (int) v;
}


public boolean thisPoint(int i, int x, int y) {
    if( ( px[i] > x-10) && ( px[i] < x+10 ) )
        if( ( py[i] > y-10 ) && ( py[i] < y+10 ) )
            return true;
    return false;
}

void setPoint(int i, int x, int y){
    if( ( i > -1) && ( i < 4 ) ){
        px[i] = x;
        py[i] = y;
    }
}

}


class DetailHandler implements MouseMotionListener, MouseListener {
private bezier c;
private int selected = -10;

public DetailHandler( bezier curve ){ 
    c = curve; 
}

public void mouseClicked( MouseEvent e ){
    c.update( e );
    c.drawControlPoint();
    if ( c.getCount() == 4 )
        c.repaint();
}

public void mouseDragged( MouseEvent e ){
    if ( selected > -1 ){
     	c.setPoint( selected, e.getX(), e.getY() );
        c.repaint();
    }
}

public void mousePressed( MouseEvent e ){
    if( c.getCount() >= 4 ){
        for( int i = 0; i < 4; i++ ){
            if ( c.thisPoint( i, e.getX(), e.getY() ))
                selected = i;
	}
    }
}

public void mouseReleased( MouseEvent e ){
	selected = -10;
}

public void mouseEntered( MouseEvent e ){}
public void mouseExited( MouseEvent e ){}
public void mouseMoved( MouseEvent e ){}

}




///////////////////////////////////////
//
//  File: bezier.html
//
///////////////////////////////////////

<
html>
<
applet code="bezier.class" width=500 height=500>
<
/applet>
<
/html>




2)
///////////////////////////////////////
//
//  File: triangle.java
//
///////////////////////////////////////

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class triangle extends Applet implements ActionListener{
TextField rotationAngle;
int angle = 0, centerX, centerY, dist;
double d1, d2;
int vx[], vy[];

public void init() {
    Label prompt = new Label("Enter angle (in degrees) to rotate:");
    add( prompt );
		
    rotationAngle = new TextField( 8 );
    add( rotationAngle );	

    centerX = (int)( getSize().width / 2 );
    centerY = (int)( getSize().height / 2 );
    dist = (int)( getSize().height / 4 );
    d1 = Math.sqrt(3) * dist /2 ;
    d2 = dist/2;
    vx = new int[ 3 ];
    vy = new int[ 3 ];
    vx[ 0 ] = centerX ;
    vy[ 0 ] = centerY - dist;      // define top corner of the triangle 
    vx[ 1 ] = centerX - (int) d1 ;
    vy[ 1 ] = centerY + (int) d2 ; // define left corner of the triangle
    vx[ 2 ] = centerX + (int) d1 ;
    vy[ 2 ] = centerY + (int) d2 ; // define right corner of the triangle

    rotationAngle.addActionListener( this );
//  repaint();
}
	
public void paint( Graphics g ) {
    int cx, cy, nx, ny;
    double theta = angle*Math.PI/180;
    double cos = Math.cos( theta );
    double sin = Math.sin( theta );

    for (int i=0; i < 3; i++ ) {// compute new location of vertices
        int xtemp = vx[ i ];
        int ytemp = vy[ i ];
        vx[ i ] = (int)( cos*(xtemp-centerX) - sin*(ytemp-centerY) + centerX );
        vy[ i ] = (int)( sin*(xtemp-centerX) + cos*(ytemp-centerY) + centerY );
    }

    cx = vx [ 2 ];
    cy = vy [ 2 ];
    for (int i=0; i < 3; i++ ) {// draw new edges
        nx = vx[ i ];
        ny = vy[ i ];
        g.drawLine( cx, cy, nx, ny );
        cx = nx;
        cy = ny;
    }
}

public void actionPerformed( ActionEvent e ){
    int newAngle = Integer.parseInt( rotationAngle.getText() );
    if ( ( newAngle >= 0 ) && ( newAngle < 90 ) ){
        showStatus( "Rotating tringle for " + newAngle + " degrees." );
        angle = newAngle;
    }
    else
        showStatus( "The angle must be between 0 and 90." );
    repaint();
}
}
//




///////////////////////////////////////
//
//  File: triangle.html
//
///////////////////////////////////////

<
html>
<
applet code="triangle.class" width=500 height=500>
<
/applet>
<
/html>




3)
///////////////////////////////////////
//
//  Midpoint Method
//
///////////////////////////////////////
Since the slope is 11/4 > 1, we consider the line segment from (0,0) to
(22,8) instead (the line segment that is symmetric to the given line
segment with respect to y=x).

In this case, we have
dx = 22
dy = 8

The plotting process for this line is:

1) plot (0,0)
   S1 = 2*8-22 = -6

2) Since S1 < 0, plot  (1,0)
   S2 = -6+2*8 = 10

3) Since S2 > 0, plot (2,1)
   S3 = 10+2*(8-22) = -18

4) Since S3 < 0, plot (3,1)
   S4 = -18+2*8 = -2

5) Since S4 < 0, plot (4,1)
   S5 = -2+2*8 = 14

6) Since S5 > 0, plot (5,2)
   S6 = 14+2*(8-22) = -14

7) Since S6 < 0, plot (6,2)
   S7 = -14+2*8 = 2

8) Since S7 > 0, plot (7,3)
   ...

To find the points that should be plotted for the given line segment
at x=2, identify the points plotted for the new line whose y coordinates
are 2. We have two points: (5,2) and (6.2).
Hence, at x=2, we should plot (2,5) and (2,6) for the given line segment.