<< Chapter < Page Chapter >> Page >

Listing 34 . Source code for the program named StringArt04.

/*StringArt04.java Copyright 2008, R.G.BaldwinRevised 03/03/08 This program animates the behavior of the earlier programnamed StringArt03. See the comments at the beginning of that program for a description of both programs. The onlysignificant difference in the behavior of the two programs is that this program slows the rotation processdown so that the user can see it happening in real time. Of course, quite a few changes were required to convertthe program from a static program to an animated program. Tested using JDK 1.6 under WinXP.*********************************************************/ import java.awt.*;import javax.swing.*; import java.awt.geom.*;import java.awt.event.*; class StringArt04{public static void main(String[] args){GUI guiObj = new GUI(); }//end main}//end controlling class StringArt04 //======================================================//class GUI extends JFrame implements ActionListener{ //Specify the horizontal and vertical size of a JFrame// object. int hSize = 300;int vSize = 470; Image osi;//an off-screen imageint osiWidth;//off-screen image width int osiHeight;//off-screen image heightMyCanvas myCanvas;//a subclass of Canvas Graphics2D g2D;//off-screen graphics context.JTextField numberPointsField;//User input field. JTextField loopsField;//User input field.int numberPoints = 6;//Can be modified by the user.int loopLim = 1;//Can be modified by the user.JTextField zRotationField;//User input field JTextField xRotationField;//User input fieldJTextField yRotationField;//User input field double zRotation;//Rotation around z in degrees.double xRotation;//Rotation around x in degrees. double yRotation;//Rotation around y in degreesJTextField xAnchorPointField;//User input fieldJTextField yAnchorPointField;//User input field JTextField zAnchorPointField;//User input fielddouble xAnchorPoint;//Rotation anchor point. double yAnchorPoint;//Rotation anchor point.double zAnchorPoint;//Rotation anchor point.GM01.Point3D anchorPoint; // boolean animate = false;//The following variable is used to refer to an array// object containing the points that define the // vertices of a geometric object.GM01.Point3D[] points;//----------------------------------------------------//GUI(){//constructor//Set JFrame size, title, and close operation.setSize(hSize,vSize); setTitle("Copyright 2008,R.G.Baldwin");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Instantiate the user input components. numberPointsField =new JTextField("6");loopsField = new JTextField("1"); zRotationField = new JTextField("0");xRotationField = new JTextField("0"); yRotationField = new JTextField("0");xAnchorPointField = new JTextField("0"); yAnchorPointField = new JTextField("0");zAnchorPointField = new JTextField("0"); JButton button = new JButton("Animate");//Instantiate a JPanel that will house the user input // components and set its layout manager.JPanel controlPanel = new JPanel(); controlPanel.setLayout(new GridLayout(0,2));//Add the user input components and appropriate labels // to the control panel.controlPanel.add(new JLabel(" Number Points")); controlPanel.add(numberPointsField);controlPanel.add(new JLabel(" Number Loops")); controlPanel.add(loopsField);controlPanel.add(new JLabel( " Rotate around Z (deg)"));controlPanel.add(zRotationField); controlPanel.add(new JLabel(" Rotate around X (deg)")); controlPanel.add(xRotationField);controlPanel.add(new JLabel( " Rotate around Y (deg)"));controlPanel.add(yRotationField); controlPanel.add(new JLabel(" X anchor point"));controlPanel.add(xAnchorPointField); controlPanel.add(new JLabel(" Y anchor point"));controlPanel.add(yAnchorPointField); controlPanel.add(new JLabel(" Z anchor point"));controlPanel.add(zAnchorPointField); controlPanel.add(button);//Add the control panel to the SOUTH position in the // JFrame.this.getContentPane().add( BorderLayout.SOUTH,controlPanel);//Create a new drawing canvas and add it to the// CENTER of the JFrame above the control panel. myCanvas = new MyCanvas();this.getContentPane().add( BorderLayout.CENTER,myCanvas);//This object must be visible before you can get an // off-screen image. It must also be visible before// you can compute the size of the canvas. setVisible(true);//Make the size of the off-screen image match the// size of the canvas. osiWidth = myCanvas.getWidth();osiHeight = myCanvas.getHeight();//Create an off-screen image and get a graphics // context on it.osi = createImage(osiWidth,osiHeight); g2D = (Graphics2D)(osi.getGraphics());//Translate the origin to the center of the off-screen // image.GM01.translate(g2D,0.5*osiWidth,-0.5*osiHeight);//Register this object as an action listener on the // button.button.addActionListener(this); //Cause the overridden paint method belonging to// myCanvas to be executed. myCanvas.repaint();}//end constructor//----------------------------------------------------////The purpose of this method is to draw the appropriate // material onto the off-screen image.void drawOffScreen(Graphics2D g2D){ //Erase the off-screen image and draw new axes.setCoordinateFrame(g2D); //The following ColMatrix3D object must be populated// with three rotation angles in degrees that // specify the following rotational angles in order// according to the right-hand rule as applied to // the indicated axis.// Rotate around z, in x-y plane // Rotate around x, in y-z plane// Rotate around y, in x-z plane GM01.ColMatrix3D angles = new GM01.ColMatrix3D(zRotation,xRotation,yRotation);//The following code causes the anchor point to be // drawn and the points in the array to be rotated.g2D.setColor(Color.BLACK); anchorPoint.draw(g2D);for(int cnt = 0;cnt<numberPoints;cnt++){ points[cnt]= points[cnt].rotate(anchorPoint,angles); }//end for loop//Implement the algorithm that draws lines connecting// points on the geometric object. GM01.Line3D line;//Begin the outer loop.for(int loop = 1;loop<= loopLim;loop++){ //The following variable specifies the array// element containing a point on which a line will // start.int start = -1;//The following variable specifies the number of // points that will be skipped between the starting// point and the ending point for a line. int skip = loop;//The following logic causes the element number to // wrap around when it reaches the end of the// array. while(skip>= 2*numberPoints-1){ skip -= numberPoints;}//end while loop//The following variable specifies the array // element containing a point on which a line will// end. int end = start + skip;//Begin inner loop. This loop actually constructs // the GM01.Line3D objects and causes visual// manifestations of those objects to be drawn on // the off-screen image. Note the requirement to// wrap around when the element numbers exceed the // length of the array.for(int cnt = 0;cnt<numberPoints;cnt++){ if(start<numberPoints-1){ start++;}else{ //Wrap aroundstart -= (numberPoints-1); }//end elseif(end<numberPoints-1){ end++;}else{ //Wrap around.end -= (numberPoints-1); }//end else//Create some interesting colors.g2D.setColor(new Color(cnt*255/numberPoints, 127+cnt*64/numberPoints,255-cnt*255/numberPoints));//Create a line that connects points on the // geometric object.line = new GM01.Line3D(points[start],points[end]); line.draw(g2D);}//end inner loop }//end outer loop}//end drawOffScreen //----------------------------------------------------////This method is used to draw orthogonal // 3D axes on the image that intersect at the origin.private void setCoordinateFrame( Graphics2D g2D){//Erase the screeng2D.setColor(Color.WHITE); GM01.fillRect(g2D,-osiWidth/2,osiHeight/2,osiWidth,osiHeight); //Draw x-axis in REDg2D.setColor(Color.RED); GM01.Point3D pointA = new GM01.Point3D(new GM01.ColMatrix3D(-osiWidth/2,0,0)); GM01.Point3D pointB = new GM01.Point3D(new GM01.ColMatrix3D(osiWidth/2,0,0)); new GM01.Line3D(pointA,pointB).draw(g2D);//Draw y-axis in GREENg2D.setColor(Color.GREEN); pointA = new GM01.Point3D(new GM01.ColMatrix3D(0,-osiHeight/2,0)); pointB = new GM01.Point3D(new GM01.ColMatrix3D(0,osiHeight/2,0)); new GM01.Line3D(pointA,pointB).draw(g2D);//Draw z-axis in BLUE. Make its length the same as the// length of the x-axis. g2D.setColor(Color.BLUE);pointA = new GM01.Point3D( new GM01.ColMatrix3D(0,0,-osiWidth/2));pointB = new GM01.Point3D( new GM01.ColMatrix3D(0,0,osiWidth/2));new GM01.Line3D(pointA,pointB).draw(g2D); }//end setCoordinateFrame method//----------------------------------------------------////This method is called to respond to a click on the // button.public void actionPerformed(ActionEvent e){ //Get user input values and use them to modify several// values that control the drawing. numberPoints = Integer.parseInt(numberPointsField.getText()); loopLim = Integer.parseInt(loopsField.getText());//Rotation around z in degrees.zRotation = Double.parseDouble(zRotationField.getText());//Rotation around x in degrees. xRotation =Double.parseDouble(xRotationField.getText()); //Rotation around y in degreesyRotation = Double.parseDouble(yRotationField.getText());//Rotation anchor point values. xAnchorPoint =Double.parseDouble(xAnchorPointField.getText()); yAnchorPoint =Double.parseDouble(yAnchorPointField.getText()); zAnchorPoint =Double.parseDouble(zAnchorPointField.getText()); //The following object contains the 3D coordinates// of the point around which the rotations will // take place.anchorPoint = new GM01.Point3D( new GM01.ColMatrix3D(xAnchorPoint,yAnchorPoint,zAnchorPoint)); //Instantiate a new array object with a length// that matches the new value for numberPoints. points = new GM01.Point3D[numberPoints];//Create a set of Point3D objects that specify // locations on the circumference of a circle that// is in the x-y plane with a radius of 50 units. Save // references to the Point3D objects in the array.for(int cnt = 0;cnt<numberPoints;cnt++){ points[cnt]= new GM01.Point3D( new GM01.ColMatrix3D(50*Math.cos((cnt*360/numberPoints)*Math.PI/180), 50*Math.sin((cnt*360/numberPoints)*Math.PI/180),0.0)); }//end for loop that creates the points//Spawn an animation thread Animate animate = new Animate();animate.start();}//end actionPerformed //====================================================////This is an inner class of the GUI class. class MyCanvas extends Canvas{//Override the update method to eliminate the default // clearing of the Canvas in order to reduce or// eliminate the flashing that that is often caused by // such default clearing.//In this case, it isn't necessary to clear the canvas // because the off-screen image is cleared each time// it is updated. This method will be called when the // JFrame and the Canvas appear on the screen or when// the repaint method is called on the Canvas object. public void update(Graphics g){paint(g);//Call the overridden paint method. }//end overridden update()//Override the paint() method. The purpose of the// paint method is to display the off-screen image on // the screen. This method is called by the update// method above. public void paint(Graphics g){g.drawImage(osi,0,0,this); }//end overridden paint()}//end inner class MyCanvas //====================================================////This is an animation thread.class Animate extends Thread{ public void run(){//Compute incremental rotation values. int steps = 100;//Number of steps in the animation.double zRotationInc = zRotation/steps; double xRotationInc = xRotation/steps;double yRotationInc = yRotation/steps;//Do the animated rotation in three distinct stages, // rotating around one axis during each stage.for(int axis = 0;axis<3;axis++){ for(int cnt = 0;cnt<steps;cnt++){ //Select the axis about which the image will// be rotated during this step.. if(axis % 3 == 0){zRotation = zRotationInc; xRotation = 0;yRotation = 0; }else if(axis % 3 == 1){zRotation = 0; xRotation = xRotationInc;yRotation = 0; }else if(axis % 3 == 2){zRotation = 0; xRotation = 0;yRotation = yRotationInc; }//end else//Draw a new off-screen image based on // user input values.drawOffScreen(g2D); //Copy off-screen image to canvas.myCanvas.repaint(); //Sleep for ten milliseconds.try{ Thread.currentThread().sleep(10);}catch(InterruptedException ex){ ex.printStackTrace();}//end catch }//end for loop}//end for loop on axis }//end run}//end inner class named Animate //====================================================//}//end class GUI

Exercises

Exercise 1

Using Java and the game-math library named GM01 , or using a different programming environment of your choice, write a program that createsthe wireframe drawing of half of a sphere protruding upward from the x-z plane as shown in Figure 11 . The north and south poles of the sphere lie on the y-axis. The x-z plane intersectsthe sphere at the equator and only the northern hemisphere is visible.

Cause your name to appear in the screen output in some manner.

Figure 11 Screen output from Exercise 1.

Missing image.

Exercise 2

Using Java and the game-math library named GM01 , or using a different programming environment of your choice, write a program that demonstrates your ability to animate two or more objects and have them moving around in a 3D world.

Cause your name to appear in the screen output in some manner.

Exercise 3

Beginning with a 3D world similar to the one that you created in Exercise 2 , demonstrate your ability to cause your program to recognize when two of your animated objects collide and to dosomething that can be noticed by a human observer when the collision occurs.

Cause your name to appear in the screen output in some manner.

Exercise 4

Beginning with a program similar to the one that you wrote in Exercise 1 , create a wireframe drawing of a complete sphere as shown in Figure 12 . The north and south poles of the sphere lie on the y-axis. As before, the x-z plane intersects thesphere at the equator, but in this case, the entire sphere is visible.

Figure 12 Screen output from Exercise 4.

Missing image.

Exercise 5

Beginning with a program similar to the one that you wrote in Exercise 1 , create a wireframe drawing of one-eighth of a sphere as shown in Figure 13 . The north and south poles of the sphere lie on the y-axis. As before, the x-z plane intersects thesphere at the equator. In this case, only that portion of the sphere described by positive coordinate values is visible.

Cause your name to appear in the screen output in some manner.

Figure 13 Screen output from Exercise 5.

Missing image.

-end-

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Game 2302 - mathematical applications for game development. OpenStax CNX. Jan 09, 2016 Download for free at https://legacy.cnx.org/content/col11450/1.33
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Game 2302 - mathematical applications for game development' conversation and receive update notifications?

Ask