Forums: » Register « |  Free Tools |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |

New Free Tools on Dev Shed!

#1
November 4th, 2012, 09:48 PM
 Shaun_B
Contributing User

Join Date: Sep 2012
Posts: 62
Time spent in forums: 1 Day 1 h 9 m 54 sec
Reputation Power: 3
Almost fixed: rotating a 2D shape.

Okay, so I've discovered the problem with rotating my shape around the centre point of it, so the code is still not yet perfect, but this is at least it's working to be a good enough starting point.

The comments should explain everything well enough I hope. I also added a scrolly text on the showStatus thingy in a true old-skool stylee. Here's the code:
Java Code:
 Original - Java Code
```import java.awt.*;import javax.swing.*;import java.awt.Graphics;import java.lang.Math;/** * This will draw a five-point star in an Applet and then * bounce it around the canvas whilst rotating it ~1° clockwise. * The alogrithmn is still imperfect, so there's some work to * do but it's about >75% accurate. *  * @author Shaun B  * @version 1.0.0a * @todo    Perfect the maths so that it is >99% accurate when *          rotating more complex shapes. Find the size in pixels *          of the rotated shape against the original. */public class starAnimation extends JApplet implements Runnable{    // This array will draw a simple star:    private static final int STAR[] =     {        /** co-ordinates in array read as         * x0, y0 to x1, y1. -1 terminates */         0, 28, 30, 28,        39,  0, 50, 28,        79, 28, 55, 46,        64, 73, 40, 57,        15, 73, 23, 45,        -1, -1    };    // This is a rhombus:    private static int square[] =    {         0,  0, 80,  0,        80, 80,  0, 80,        -1, -1    };    // Here is our buffer for the shape:    private static int buffer[] =    {        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1,        -1, -1, -1, -1    };    // Here's a scrolly messahe:    private static String scrolly= " Nah nah na na nahh! :-P  Donkeysoft MMXII ";    private static String charBuffer = "";    private byte updateScrolly = 0;    // This will be used to rotate the shape, theta is    // converted to radians and therefore degrees    // can be within a more human range between zero    // and 360. The PI representation is accurate according    // to the Sinclair ZX81 :-)    private static double theta = (double)(1*3.1415927)/180;    private static double degrees = (double)0;    // Identity matrix and rotation matrix not yet    // implemented    /**private static int identity[][]=    {        { 1, 0, 0, 0 },        { 0, 1, 0, 0 },        { 0, 0, 1, 0 }        { 0, 0, 0, 1 }    };    private static double matrixRotate[][] =     {        { Math.cos(0.10),   Math.sin(0.10),    0.00,   0.00 },        { Math.sin(0.10),   Math.cos(0.10),     0.00,   0.00 },        { 0.00,             0.00,               0.10,   0.00 },        { 0.00,             0.00,               0.00,   0.10 }    };*/    // Starting position of star:    private int xAxis = 0;    private int yAxis = 0;    // Sets the height and width of the image:    private int widthOfStar = 80;    private int heightOfStar = 73;    private int widthOfSquare = 80;    private int heightOfSquare = 80;    // Sets the direction of the animation    // positive to move right/down and negative    // to move left/up:    private int xDirection = 1;    private int yDirection = 1;    // This will be used to get the width and height of the Applet    private int width=0;    private int height=0;    // This will be used to index through the array above:    private int index=0;    // Read up about back buffering, as it's important ;-)    private Image backBuffer = null;    private Graphics backg = null;    // This will be our thread, you need to know about threads too:    private Thread runner = null;     /**     * Called by the browser or applet viewer to inform this JApplet that it     * has been loaded into the system. It is always called before the first      * time that the start method is called.     */    @Override    public void init()    {        // This is a workaround for a security conflict with some browsers        // including some versions of Netscape & Internet Explorer which do         // not allow access to the AWT system event queue which JApplets do         // on startup to check access. May not be necessary with your browser.         JRootPane rootPane = this.getRootPane();            rootPane.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);        // Provide any initialisation necessary for your JApplet        // Gets the current width and height and creates a back buffer        // to that height:        this.width = getSize().width;        this.height = getSize().height;        this.backBuffer = createImage(width, height);        // Creates instance of the back buffer:        this.backg = backBuffer.getGraphics();        // Sets default behaviour as focusable:        this.setFocusable(true);        this.setVisible(true);    }    public void animate(int x, int y, int img[])    {        boolean xAndY = (x>=0) && (y>=0);        if(!xAndY)        {            showStatus("Problem with Animate");        }        rotate(x, y, img);    }    public void scrollText()    {       int stringLength = this.scrolly.length();       this.charBuffer=""+this.scrolly.charAt(0);       String stringBuffer = ""+            this.scrolly.substring(1, stringLength)+charBuffer;       this.scrolly = stringBuffer;    }    public void rotate(int x, int y,int [] img)    {        do        {            this.buffer[index]=img[index];            this.index++;        }while(img[index]>=0);        this.buffer[index+0]=-1;        this.buffer[index+1]=-1;        this.index=0;        this.heightOfStar = heightOfObject(heightOfStar, img);        this.widthOfStar = widthOfObject(widthOfStar, img);        // Divides width and height in half        int px=widthOfStar>>>1;        int py=heightOfStar>>>1;        // Sets up variables for the maths:        double x2=0.00;        double y2=0.00;        double x1=0.00;        double y1=0.00;        // Degrees to turn:        if(this.degrees>360)        {            this.degrees = (double)0;        }        this.degrees += (double)1;        this.theta = (double)(degrees*3.1415)/180;        while(this.buffer[index]>=0)        {            x1 = buffer[index+0];            y1 = buffer[index+1];            x2 = (double)px+(px-x1)*Math.cos(theta)-(py-y1)*Math.sin(theta);            y2 = (double)py+(px-x1)*Math.sin(theta)+(py-y1)*Math.cos(theta);            buffer[index+0]=(int)x2*1;            buffer[index+1]=(int)y2*1;            index += 2;        }        this.index = 0;        // Calls drawImage method:        this.drawImage(x, y, buffer);    }    public void drawImage(int x, int y, int [] img)    {        do        {            if(this.buffer[index]!=img[index])            {                System.err.println("Image not recognised");            }            this.index++;        }while(img[index]>=0);        this.index = 0;        int x0 = 0;        int y0 = 0;        int x1 = 0;        int y1 = 0;        // Sets the default foreground colour:        backg.setColor(Color.black);        // This will step through the array points to draw        // the star object. There is probably also a fillPolygon        // or drawPolygon method that could also be used:        while(this.buffer[index]>=0)        {            x0 = x+(this.buffer[index+0]);            y0 = y+(this.buffer[index+1]);            if (this.buffer[index+2]!=-1 && this.buffer[index+3]!=-1)            {                x1 = x+(this.buffer[index+2]);                y1 = y+(this.buffer[index+3]);            }            else            {                // Back to the start:                x1 = x+(this.buffer[0]);                y1 = y+(this.buffer[1]);            }            this.backg.drawLine( x0, y0, x1, y1 );            this.index += 2;        }        // Resets index to zero, incase the JApplet is reloaded or something:        this.index = 0;    }    public void clearBackBuffer()    {        // This will clear the canvas so that there is no trail left by the star        // by setting the default background colour and then filling it to the        // width and height of the canvas:        this.backg.setColor(Color.white);        this.backg.fillRect(0, 0, this.width, this.height);    }    /**     * Called by the browser or applet viewer to inform this JApplet that it      * should start its execution. It is called after the init method and      * each time the JApplet is revisited in a Web page.      */    @Override    public void start()    {       // Sets up the thread:       if(this.runner == null)       {           this.runner = new Thread(this);           this.runner.start();       }       // Call to parent (not needed):       // super.start();    }    /**      * Called by the browser or applet viewer to inform this JApplet that     * it should stop its execution. It is called when the Web page that     * contains this JApplet has been replaced by another page, and also     * just before the JApplet is to be destroyed.      */    @Override    public void stop()    {        // Call to parent:        super.stop();    }    public int heightOfObject(int currentHeight, int [] obj)    {        this.index = 1;        while(obj[index]!=-1)        {            if(obj[index]>currentHeight)            {                currentHeight=obj[index];            }            this.index +=2;        }        this.index = 0;        return currentHeight;    }    public int widthOfObject(int currentWidth, int [] obj)    {        while(obj[index]!=-1)        {            if(obj[index]>currentWidth)            {                currentWidth=obj[index];            }            this.index +=2;        }        this.index = 0;        return currentWidth;    }    @Override    public void run()    {        // Checks if this thread has been set to runnable in the start method:        Thread thisThread = Thread.currentThread();        while (runner == thisThread)        {            // Calls our method to draw the star:            animate(xAxis, yAxis, STAR);            try            {                // This is the time that it will pause in milliseconds                // 1000 = 1 second:                Thread.sleep(33);            }            catch (InterruptedException e)            {            }            repaint();            // This will move the x and y co-ordinates of our object:            this.xAxis += this.xDirection;            this.yAxis += this.yDirection;            // This will check the boundries of the current applet canvas:            if(xAxis >= (width-widthOfStar))            {                this.xDirection =-1;            }            if(xAxis <= 0)            {                this.xDirection = 1;            }            if(yAxis >= (height-heightOfStar))            {                this.yDirection =-1;            }            if(yAxis <= 0)            {                this.yDirection = 1;            }            // Clears the canvas, so there is no 'trail'            // left by the moving star:            clearBackBuffer();            this.updateScrolly++;            if(this.updateScrolly>128)            {                this.updateScrolly = 0;            }            if(this.updateScrolly%4 == 0)            {                scrollText();            }            showStatus(scrolly);        }    }    // Main paint method (called on repaint(); I think):    @Override    public void paint(Graphics g)    {        // Calls to the update method:        update(g);    }    public void update(Graphics g)    {        // Gets the backBuffer and draws it to the canvas:        g.drawImage(backBuffer,0,0,this);        // the sync toolkit is used for animations as it stops flicker:        getToolkit().sync();    }    /**     * Called by the browser or applet viewer to inform this JApplet that it     * is being reclaimed and that it should destroy any resources that it     * has allocated. The stop method will always be called before destroy.      */    @Override    public void destroy()    {        // Calls the garbage collector before calling parent:        this.runner = null;        super.destroy();    }}
```

Regards,

Shaun.

 Viewing: Dev Shed Forums > Programming Languages > Java Help > Almost fixed: rotating a 2D shape.