Ketan's Musings

Where he blogs about his eclipse musings

How would you clean this up ?

with 2 comments

This was an interesting piece of code from a long time mentor and friend. He’s just started to learn Java some time ago, and has written this program to demonstrate how to draw an Ellipse.

He’s about 60 years of age. Has been a long time Turbo C-2.0 programmer. Mostly he develops small graphics programs to demonstrate some engineering drawing and mechanics concepts.

import java.awt.*; // Requisite files od JAVA
import java.awt.event.*;
//import java.awt.geom.*;
import javax.swing.*;
//import java.math.*;
//import java.util.*;
  //Projest name and the following class name should be same
public class leenaTrial1 extends JFrame {
        JFrame frame = new JFrame("Applet");
        JPanel drawingArea = new JPanel(); // Drawing Area is named
        JButton b1; // Defines action Button
        int mouse_i = 1;  // Counter for action

        public void run() {
                frame.setSize(1000, 500); // Frame size is defined
                final Container content = getContentPane();
                content.setBackground(Color.lightGray);
                // color of frame or container is defined
                content.setLayout(new FlowLayout());

                drawingArea.setPreferredSize(new Dimension(750, 700));
                // Size of draw area is defined & color in the next line

                drawingArea.setBackground(Color.black);
                content.add(drawingArea);
                b1 = new JButton("Next Step"); // b1 is button for the next step
                content.add(b1);

                b1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                        Graphics g = drawingArea.getGraphics();
                        Font font20 =new Font("TimesRoman",Font.PLAIN,20);
                        Font f0nt14=new Font("TimesRoman",Font.PLAIN,14);
                        g.setFont(font20);
                        int r1 = 250, r2 = 150, x0 = 375, y0 = 415;
                        // r1, r2 semi-major & semi-minor axex, x0,y0 center of circles
                        double inc = 0.005; // increment 
                        int x1, y1, x2, y2; // Two ends of a line

                        // inner circle in 
                        if(mouse_i == 1) {
                                g.setColor(Color.white);
                                //g.drawOval(w, w, x, y);           // top, left, width, height
                                g.drawString("Step 1: Draw inner circle with the radius equal to semi-minor axis of the ellipse.", 20, 20);
                                ovalByPixels(x0,y0,r2,r2,1,Color.blue);
                     }

                        // outer circle
                         if(mouse_i == 2) {
                                g.setColor(Color.white);
                                g.drawString("Step 2: Draw outer circle with the radius equal to semi-major axis of the ellipse.", 20, 35);
                                ovalByPixels(x0,y0,r1,r1,1,Color.red); // Color spesified by name
                        }

                        // twelve lines
                         if(mouse_i == 3) {
                                g.setColor(Color.white);
                                g.drawString("Step 3: Divide the circles in twelve parts.", 20, 50);
                                for(int k = 0; k < 6; k++) {
                                        double cos = Math.cos(k*2*Math.PI/12);
                                        double sin = Math.sin(k*2*Math.PI/12);
                                        double f1 = 1.06 ; // numbers are printed out side of larger circle
                                        double f2 = 0.9 ; // numbers are printed in side of smaller circle
                                        x1 = x0 + (int)(r1*cos); // x1,y1 are on outer circle on one end of diameter
                                        y1 = y0 - (int)(r1*sin);
                                        x2 = x0 - (int)(r1*cos); // x2,y2 are on outer circle at other end of diameter
                                        y2 = y0 + (int)(r1*sin);
                                        lineByPixels(x1, y1, x2, y2,5,new Color(255,100,100)); // 5 is delay value
                                        // Color spesified by values of three colors
                                        g.drawString("a" + Integer.toString(k+1),  x0-10+ (int)(f1*r1*cos), y0+10 - (int)(f1*r1*sin));
                                        g.drawString("a" + Integer.toString(k+7),  x0-10 - (int)(f1*r1*cos), y0+10 + (int)(f1*r1*sin));
                                        g.drawString("b" + Integer.toString(k+1),  x0 -10+ (int)(f2*r2*cos), y0+10 - (int)(f2*r2*sin));
                                        g.drawString("b" + Integer.toString(k+7),  x0 -10- (int)(f2*r2*cos), y0+10 + (int)(f2*r2*sin));
                                        delay(500);        // call delay function         
                                }
                        }

                         if(mouse_i == 4) { // Step 4     * * * * * * * * * * *
                                g.setColor(Color.white);
                                g.drawString("Step 4: From inner circle points, draw horizontal lines and from corresponding points ", 20, 70);
                                g.drawString("         on the outer circle, draw vertical lines. Cutting points are points on Ellipse.", 20, 85);
                                Color cr = new Color(255,200,100);
                                for(int k = 0; k <= 11; k++) {
                                        //int x1,x2,y1,y2;
                                        x1 = x0 + (int)(r1*Math.cos((2*Math.PI/12)*k)); // point on outer circle
                                        y1 = y0 - (int)(r1*Math.sin((2*Math.PI/12)*k));
                                        x2 = x0 + (int)(r2*Math.cos((2*Math.PI/12)*k)); //points on inner circle
                                        y2 = y0 - (int)(r2*Math.sin((2*Math.PI/12)*k));
                                        int x1L = x0 + (int)(1.2*r1*Math.cos((2*Math.PI/12)*k)); // point on outer circle
                                        int y2L = y0 - (int)(0.9*r2*Math.sin((2*Math.PI/12)*k));
                                        g.setColor(Color.green);
                                        if(k==3 || k==9){
                                                lineByPixels(x0-20, y2, x0+20, y2,5,cr );}// 5 is delay value
                           //g.drawLine( x0-20, y2, x0+20, y2);}
                                        else{
                                                lineByPixels(x2, y2, x1L, y2,5,new Color(255,100,200));}
                                                //g.drawLine(x2, y2, x1L, y2);} // horizontal line
                                        g.setColor(Color.yellow);
                                        if(k==0 || k==6){
                                                lineByPixels(x1, y0-20, x1,  y0+20,5,new Color(100,100,200));}
                                                //g.drawLine(x1, y0-20, x1,  y0+20);}// Vertical line
                                        else {
                                                lineByPixels(x1, y1, x1, y2L,5,new Color(100,255,100));}
                                                //g.drawLine(x1, y1, x1, y2L);}// vertical line
                                        delay(500); // call delay function         
                                        g.setColor(Color.white);
                                        g.drawOval(x1-3, y2-3, 6, 6); // Box (top, left, width, height
                    delay(500);
                                }
                        }

                        if(mouse_i == 5) {
                                g.setColor(Color.white);
                                g.drawString("Step 5: Draw a smooth curve connecting the twelve cutting points.", 20, 100);
                                g.setColor(Color.RED);
                                for(double i = 0; i < 2*(3.1415926); i=i+inc) {
                                        g.drawLine((int)(x0+r1*Math.cos(i)), (int)(y0-r2*Math.sin(i)), (int)(x0+(r1+1)*Math.cos(i)), (int)(y0-(r2+1)*Math.sin(i)));
                                        delay(1); // calls delay function

                                } // Ellipse drawing is complete

                                g.drawString("Ellipse by Concentric Circles, by Dr. Vasant D. Barve", 20, 680);
                                g.drawString("DONE!", 670, 350);
                        }
                        mouse_i++;
                 }
                });

                pack();
                setVisible(true);
        }
    // This is delay procedure  
        public void delay(int dt1)
        {
                try {
                        Thread.sleep(dt1);
                }
                catch (InterruptedException e) {
                }
        } // Delay procedure ends

    // This is Oval (circle or ellipse) by pixel procedure   * * * * * * * * * * * * * * *      
        public void ovalByPixels(float x0, float y0, float r1, float r2, int dt, Color objColor)
        {   // Center of circle at x0,y0 Radius r dt delay after each pixel counterclckwise
                Graphics g = drawingArea.getGraphics();
                double rm = Math.max(r1, r2); // Greater of the two picked up
                for(double i = 0; i < 2*(3.1415926); i=i+1/rm) {
                        double x1 = x0+ r1*Math.cos(i);
                        double y1 = y0+r2*Math.sin(i);
                        double x2 = x0+(r1+1)*Math.cos(i);
                        double y2 = y0+(r2+1)*Math.sin(i);
                        g.setColor(objColor);
                        g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);
                        delay(dt); // call delay function    
                }
        } // OvalByPixels procedure Ends

//       lineByPixels Procedure starts              * * * * * *  * * * * *
        public void lineByPixels(int x1, int y1, int x2, int y2, int dt,Color objCol ) {
                // Line starts at (x1,y1) & ends at (x2,y2) each point is drawn as short line of one pixel length
                Graphics g = drawingArea.getGraphics();
                //g.setColor(Color.white); 
                g.setColor(objCol);

                int L= (int) Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
            // length of line is found
                double th=Math.atan2(y2-y1,x2-x1); // inclination of line with x axis
               for(int i=0; i<=L-1; i=i+1)
            { g.drawLine((int) (x1+i*Math.cos(th)), (int) (y1+i*Math.sin(th)),(int) (x1+(i+1)*Math.cos(th)), (int) (y1+(i+1)*Math.sin(th)));
          delay(dt);    //delay introduced to see line being drawn    
            }
        } // lineByPixels Procedure Ends

        // Paint graphics starts                     * * * * * * * * *
        public void paint(Graphics g) {
                super.paint(g);
        } // Paint graphics Ends

        public static void main(String[] args) {
                leenaTrial1 ecc = new leenaTrial1(); // here the function is called
                ecc.run();
        }
}

Written by Ketan

February 14th, 2007 at 1:14 pm

2 Responses to 'How would you clean this up ?'

Subscribe to comments with RSS or TrackBack to 'How would you clean this up ?'.

  1. Is It worth doing it? I think this program is performing some calculation and is small enough not to improve it. I’ve wrote a number of graphics programs, in C#, VB and Java, like this which ended up in graphics API calls and arithmetic.

    and its sufficiently difficult to isolate computation from device operation, may be you can isolate computation with a graphics device abstraction layer between it, but is it worth doing it?

    Nirav Thaker

    16 Feb 07 at 2:30 pm

  2. Yes,

    It is indeed worth cleaning this up.

    As I’ve already stated, this is written by a self-taught 60+ year old person, who understands in a way that this can be written better.

    From my personal experiences in doing engineering drawing, and during my brief project on 3D modeling during my BE, I understand that there’s a lot of “utility code” that just computes angles, lengths, co-ordinates, among a lot of other things.

    This particular program is no different. Most of it deals with the above mentioned “utility code”. I’ve been (to some extent) able to refactor this into some utility classes.

    It is still not all that elegant, but for starters, it is far more elegant than the existing design, without going gungho about a lot of stuff like design patterns, tests and the works!

    Ketan

    19 Feb 07 at 10:57 am

Leave a Reply

IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)

What is 4 + 13 ?
Please leave these two fields as-is: