LINE DRAWINGS IN APPLETS

CONTENTS

1. Introduction
2. Arrow drawing



1. INTRODUCTION

One way of getting line darwing into html pages is to create the drawing using some drawing package, save it as a gif, and then load this file into the html page using the IMG tag. This is rather longwinded, if the drawing is reasonably simple, it is easier to write an applet containing appropriate drawing methods to create the drawing. An example of this is given here.



2. ARROW DRAWING

The java.awtpackage contains many drawing methods but no method to draw arraows. We have created one here (Table 1); note that the code makes use of the fillPolygon method. The associated html code and output is given in Table 2 and some example output in Figure 1.

// Draw Arrow
// Frans Coenen
// University of Liverpool, Dept of Comp. Sci.
// Friday 12 January 2002

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

public class DrawArrow extends Applet {

    int al = 8;		// Arrow length
    int aw = 6;		// Arrow width
    int haw = aw/2;	// Half arrow width
    int xValues[] = new int[3];
    int yValues[] = new int[3];
    
    // Override init()
                                       
    public void init() {
        setBackground(Color.white);
        }
                                           
    // Overide paint()
                                       
    public void paint(Graphics g) {
	drawArrow(g, 10, 10,60,60);	
	drawArrow(g,110, 10,60,60);
	drawArrow(g,110,110,60,60);
	drawArrow(g, 10,110,60,60);
	}
    
    public void drawArrow(Graphics g, int x1, int y1, int x2, int y2) {
        // Draw line
	g.drawLine(x1,y1,x2,y2);
	// Calculate x-y values for arrow head
	calcValues(x1,y1,x2,y2);
	g.fillPolygon(xValues,yValues,3);
	}

    /* CALC VALUES: Calculate x-y values. */
    	
    public void calcValues(int x1, int y1, int x2, int y2) {
	// North or south	
	if (x1 == x2) { 
	    // North
	    if (y2 < y1) arrowCoords(x2,y2,x2-haw,y2+al,x2+haw,y2+al);
	    // South
	    else arrowCoords(x2,y2,x2-haw,y2-al,x2+haw,y2-al);
	    return;
	    }	
	// East or West	
	if (y1 == y2) {
	    // East
	    if (x2 > x1) arrowCoords(x2,y2,x2-al,y2-haw,x2-al,y2+haw);
	    // West
	    else arrowCoords(x2,y2,x2+al,y2-haw,x2+al,y2+haw);
	    return;
	    }
	// Calculate quadrant
	
	calcValuesQuad(x1,y1,x2,y2);
	}

    /* CALCULATE VALUES QUADRANTS: Calculate x-y values where direction is not
    parallel to eith x or y axis. */
    
   public void calcValuesQuad(int x1, int y1, int x2, int y2) { 
	double arrowAng = Math.toDegrees (Math.atan((double) haw/(double) al));
	double dist = Math.sqrt(al*al + aw);
	double lineAng = toDegrees(Math.atan(((double) Math.abs(x1-x2))/
                            ((double) Math.abs(y1-y2))));
				
	// Adjust line angle for quadrant
	if (x1 > x2) {
	    // South East
	    if (y1 > y2) lineAng = 180.0-lineAng;
	    }
	else {
	    // South West
	    if (y1 > y2) lineAng = 180.0+lineAng;
	    // North West
	    else lineAng = 360.0-lineAng;
	    }
	
	// Calculate coords
	
	xValues[0] = x2;
	yValues[0] = y2;	
	calcCoords(1,x2,y2,dist,lineAng-arrowAng);
	calcCoords(2,x2,y2,dist,lineAng+arrowAng);
	}
    
    /* CALCULATE COORDINATES: Determine new x-y coords given a start x-y and
    a distance and direction */
    
    public void calcCoords(int index, int x, int y, double dist, 
    		double dirn) {
	System.out.println("dirn = " + dirn);
	while(dirn < 0.0)   dirn = 360.0+dirn;
	while(dirn > 360.0) dirn = dirn-360.0;
	System.out.println("dirn = " + dirn);
		
	// North-East
	if (dirn <= 90.0) {
	    xValues[index] = x + (int) (Math.sin(Math.toRadians(dirn))*dist);
	    yValues[index] = y - (int) (Math.cos(Math.toRadians(dirn))*dist);
	    return;
	    }
	// South-East
	if (dirn <= 180.0) {
	    xValues[index] = x + (int) (Math.cos(Math.toRadians(dirn-90))*dist);
	    yValues[index] = y + (int) (Math.sin(Math.toRadians(dirn-90))*dist);
	    return;
	    }
	// South-West
	if (dirn <= 90.0) {
	    xValues[index] = x - (int) (Math.sin(Math.toRadians(dirn-180))*dist);
	    yValues[index] = y + (int) (Math.cos(Math.toRadians(dirn-180))*dist);
	    }
	// Nort-West    
	else {
	    xValues[index] = x - (int) (Math.cos(Math.toRadians(dirn-270))*dist);
	    yValues[index] = y - (int) (Math.sin(Math.toRadians(dirn-270))*dist);
	    }
	}      
    
    // ARROW COORDS: Load x-y value arrays */
    
    public void arrowCoords(int x1, int y1, int x2, int y2, int x3, int y3) {
        xValues[0] = x1;
	yValues[0] = y1;
	xValues[1] = x2;
	yValues[1] = y2;
	xValues[2] = x3;
	yValues[2] = y3;
	}
    } 

Table 1: Draw arrow applet

< CENTER>
< APPLET code=DrawArrow.class width=160 height=160></APPLET>
</CENTER>

Table 2: HTML file

Figure 1: Output produced by applet presented in Table 1.



AKNOWLEDGEMENTS

I would like to thank Michael Kreutzer (of --- at time of writing April 2002 --- the Institut fuer Informatik und Gesellschaft, Abteilung Telematik Universitaet Freiburg) for felpfull comments and suggestions concerning the arrow drawing algorithm presented on this WWW page.




Created and maintained by Frans Coenen. Last updated 13 June 2003