...
Objectives:
- To demonstrate an object launch to a target point
Advance:
Descriptions:
- To move your object towards a location,provided targeted location and current location, you can suppose your current location origin and then get the relative position of the target location in polar coordinate.
- This will give you the direction you need to travel.
- Given the speed you want the object to travel,
Stepped Simple example : (Click mouse to step, Hold down to see the hint, More content under demo 1, please scroll down to view Keynote 0)Please expand source to view. There's more example after this , please scroll down)
Processing Title Simplest example Height 400 title Simplest example Processing Height 600 Width 600 final int appwidth = 600; final int appheight = 600; final float stepsize = 10; targetedobject myobject; class targetedobject { // This is the object to move int mcurrentx, mcurrenty; // This will store the current location of the object int mtargetx, mtargety; // This will store the target location of the object int mtargetx_t, mtargety_t; // Step travel float mrotation; // This is the current orientation of this object float thisstep; boolean demostep; targetedobject( int x, int y, int r ) { // Initialize with coordinate and orientation mcurrentx = x; mtargetx = x; mcurrenty = y; mtargety = y; mrotation = r; demostep = false; } void updatedraw() { //Draws the shape pushMatrix(); translate( mcurrentx, mcurrenty ); rotate( mrotation ); noStroke(); fill( 255, 0, 0 ); ellipse(0, 0, 40, 40); noFill(); stroke(255); strokeWeight(5); line( -10, 0, 10, 0 ); line( 10, 0, 5, -5 ); line( 10, 0, 5, 5 ); popMatrix(); this.drawhelper(); } void drawhelper() { if ( this.demostep ) { //Need draw float textx, texty; noFill(); strokeWeight(3); stroke( 0, 255, 255, 192 ); line( this.mcurrentx, this.mcurrenty, this.mtargetx, this.mtargety ); line( this.mtargetx, this.mcurrenty, this.mtargetx, this.mtargety ); line( this.mcurrentx, this.mcurrenty, this.mtargetx, this.mcurrenty ); textSize(24); textAlign(CENTER, BOTTOM); noStroke(); fill(255); textx = (this.mtargetx + this.mcurrentx) / 2; texty = this.mcurrenty; text( "X2 - X1", textx, texty ); textAlign(LEFT, CENTER); textx = this.mtargetx; texty = (this.mtargety + this.mcurrenty) / 2; text( "Y2 - Y1", textx, texty ); textAlign(CENTER, CENTER); textx = (this.mtargetx + this.mcurrentx) / 2; texty = (this.mtargety + this.mcurrenty) / 2; text( "L", textx, texty ); } } void startstep(int x, int y) { float targetlength; float temprotation; this.demostep = true; this.mtargetx = x; this.mtargety = y; targetlength = sqrt( pow( this.mtargetx - this.mcurrentx, 2 ) + pow( this.mtargety - this.mcurrenty, 2 ) ); //Get the target distance if (targetlength <= 0.5) { this.mrotation = 0; return; //Do not move } if (targetlength > stepsize) { //Calculate step size this.thisstep = stepsize; } else { this.thisstep = targetlength; } temprotation = acos( (this.mtargetx - this.mcurrentx) / targetlength ); if ( this.mtargety > this.mcurrenty ) { //> 180 degrees this.mrotation = temprotation; }else{ this.mrotation = 2 * PI - temprotation; } // Calculate the step target this.mtargetx_t = (int)(this.thisstep * cos(this.mrotation)); this.mtargety_t = (int)(this.thisstep * sin(this.mrotation)); } void endstep() { this.demostep = false; this.mcurrentx += this.mtargetx_t; this.mcurrenty += this.mtargety_t; } } void setup() { size(appwidth, appheight); background(0); myobject = new targetedobject( width / 2, height / 2, 0 ); } void draw() { background(0); myobject.updatedraw(); } void mousePressed() { if (mouseButton == LEFT) { myobject.startstep(mouseX, mouseY); } } void mouseReleased() { if ( myobject.demostep ) { myobject.endstep(); } }
Anchor // x1, y1 are current position, x2, y2 are target position float x1, y1, x2, y2; void setup(){ size(600,400); // Set current position to centre x1 = 300; y1 = 200; } void draw(){ background(0); fill(255); // Movement code here : x2 = mouseX; y2 = mouseY; float l = sqrt( pow((x2-x1),2) + pow((y2-y1),2) ); if( l > 0.5 ){ float theta = acos((x2-x1) / l); if( y2 < y1 ){ theta = 2 * PI - theta; } x1 += 2 * cos(theta); y1 += 2 * sin(theta); } // Draw the result ellipse( x1, y1, 30, 30 ); }
Stepped example : (Click mouse to step, Hold down to see the hint, More content under demo 1, please scroll down to view Keynote 0)
Processing Height 600 Width 600 //******************************************************* // Global variables //******************************************************* final int appwidth = 600; final int appheight = 600; final float stepsize = 10; targetedobject myobject; //******************************************************* // The class of the moving object //******************************************************* class targetedobject { // This is the object to move int mcurrentx, mcurrenty; // This will store the current location of the object int mtargetx, mtargety; // This will store the target location of the object int mtargetx_t, mtargety_t; // Step travel float mrotation; // This is the current orientation of this object float thisstep; boolean demostep; // The flag whether the helper needs to be displayed or not targetedobject( int x, int y, int r ) { // Initialize with coordinate and orientation mcurrentx = x; mtargetx = x; mcurrenty = y; mtargety = y; mrotation = r; demostep = false; } void updatedraw() { // Draws the shape pushMatrix(); translate( mcurrentx, mcurrenty ); rotate( mrotation ); noStroke(); fill( 255, 0, 0 ); ellipse(0, 0, 40, 40); noFill(); stroke(255); strokeWeight(5); line( -10, 0, 10, 0 ); line( 10, 0, 5, -5 ); line( 10, 0, 5, 5 ); popMatrix(); this.drawhelper(); } void drawhelper() { if ( this.demostep ) { // Need draw helper float textx, texty; noFill(); strokeWeight(3); stroke( 0, 255, 255, 192 ); line( this.mcurrentx, this.mcurrenty, this.mtargetx, this.mtargety ); line( this.mtargetx, this.mcurrenty, this.mtargetx, this.mtargety ); line( this.mcurrentx, this.mcurrenty, this.mtargetx, this.mcurrenty ); textSize(24); textAlign(CENTER, BOTTOM); noStroke(); fill(255); textx = (this.mtargetx + this.mcurrentx) / 2; texty = this.mcurrenty; text( "X2 - X1", textx, texty ); textAlign(LEFT, CENTER); textx = this.mtargetx; texty = (this.mtargety + this.mcurrenty) / 2; text( "Y2 - Y1", textx, texty ); textAlign(CENTER, CENTER); textx = (this.mtargetx + this.mcurrentx) / 2; texty = (this.mtargety + this.mcurrenty) / 2; text( "L", textx, texty ); noFill(); strokeWeight(3); stroke(255,0,0); arc( this.mcurrentx, this.mcurrenty, 64, 64, 0, this.mrotation ); textx = this.mcurrentx + 40; texty = this.mcurrenty + 40; text( degrees(this.mrotation), textx, texty ); } } void startstep(int x, int y) { float targetlength; float temprotation; this.demostep = true; // Remember target coordinates this.mtargetx = x; this.mtargety = y; // Calculate the distance between the endpoint and start point targetlength = sqrt( pow( this.mtargetx - this.mcurrentx, 2 ) + pow( this.mtargety - this.mcurrenty, 2 ) ); //Get the target distance if (targetlength <= 0.5) { this.mrotation = 0; return; //Do not move } if (targetlength > stepsize) { //Calculate step size this.thisstep = stepsize; } else { this.thisstep = targetlength; } // Get the direction (0~180 degree(s)) temprotation = acos( (this.mtargetx - this.mcurrentx) / targetlength ); if ( this.mtargety > this.mcurrenty ) { this.mrotation = temprotation; }else{ this.mrotation = 2 * PI - temprotation; // > 180 degrees } // Calculate the step target this.mtargetx_t = (int)(this.thisstep * cos(this.mrotation)); this.mtargety_t = (int)(this.thisstep * sin(this.mrotation)); } void endstep() { this.demostep = false; // Move the object this.mcurrentx += this.mtargetx_t; this.mcurrenty += this.mtargety_t; } } //******************************************************* // Setup the size and the moving object //******************************************************* void setup() { size(appwidth, appheight); background(0); myobject = new targetedobject( width / 2, height / 2, 0 ); } //******************************************************* // Update the draw //******************************************************* void draw() { background(0); myobject.updatedraw(); } //******************************************************* // When mouse is pressed, start the stepping // Calculation process //******************************************************* void mousePressed() { if (mouseButton == LEFT) { myobject.startstep(mouseX, mouseY); } } //******************************************************* // After the mouse is released, // End the stepping and move the object //******************************************************* void mouseReleased() { if ( myobject.demostep ) { myobject.endstep(); } }
Anchor keynote00 keynote00 Processingcode title Key note //Get the target distance targetlength = sqrt( pow( this.mtargetx - this.mcurrentx, 2 ) + pow( this.mtargety - this.mcurrenty, 2 ) ); //Arc cosin adjacent side divide by Hypotenuse //OR arc sin subtense divide by Hypotenuse //Not using tangent to avoid Divide by Zero temprotation = acos( (this.mtargetx - this.mcurrentx) / targetlength ); //In this case, we are using cosin, so for the angle > 180 which means that //targety is under currend y if ( this.mtargety > this.mcurrenty ) { //> 180 degrees this.mrotation = temprotation; }else{ this.mrotation = 2 * PI - temprotation; } //Now that we have the rotation, we recalculate the x and y we need to travel this.mtargetx_t = (int)(this.thisstep * cos(this.mrotation)); this.mtargety_t = (int)(this.thisstep * sin(this.mrotation)); //Finally, move the object this.mcurrentx += this.mtargetx_t; this.mcurrenty += this.mtargety_t;
Continuous Example ( jitter is actually due to the fps not being stable )
Processing final float appwidth = 600; final float appheight = 600; final float stepsize = 5; targetedobject myobject; class targetedobject { // This is the object to move float mcurrentx, mcurrenty; // This will store the current location of the object float mtargetx, mtargety; // This will store the target location of the object float mtargetx_t, mtargety_t; // Step travel float mrotation; // This is the current orientation of this object float thisstep; boolean demostep; targetedobject( float x, float y, float r ) { // Initialize with coordinate and orientation mcurrentx = x; mtargetx = x; mcurrenty = y; mtargety = y; mrotation = r; demostep = false; } void updatedraw() { //Draws the shape pushMatrix(); translate( mcurrentx, mcurrenty ); rotate( mrotation ); noStroke(); fill( 255, 0, 0 ); ellipse(0, 0, 40, 40); noFill(); stroke(255); strokeWeight(5); line( -10, 0, 10, 0 ); line( 10, 0, 5, -5 ); line( 10, 0, 5, 5 ); popMatrix(); } void moveto(float x, float y) { this.mtargetx = x; this.mtargety = y; //Get the target distance float targetlength = sqrt( pow( this.mtargetx - this.mcurrentx, 2 ) + pow( this.mtargety - this.mcurrenty, 2 ) ); if(targetlength < 0.5){ return; } //Arc cosin adjacent side divide by Hypotenuse //OR arc sin subtense divide by Hypotenuse //Not using tangent to avoid Divide by Zero float temprotation = acos( (this.mtargetx - this.mcurrentx) / targetlength ); //In this case, we are using cosin, so for the angle > 180 which means that //targety is under currend y if ( this.mtargety > this.mcurrenty ) { //> 180 degrees this.mrotation = temprotation; } else { this.mrotation = 2 * PI - temprotation; } if (targetlength > stepsize) { //Calculate step size this.thisstep = stepsize; } else { this.thisstep = targetlength; } //Now that we have the rotation, we recalculate the x and y we need to travel this.mtargetx_t = (int)(this.thisstep * cos(this.mrotation)); this.mtargety_t = (int)(this.thisstep * sin(this.mrotation)); //Finally, move the object this.mcurrentx += this.mtargetx_t; this.mcurrenty += this.mtargety_t; } } void setup() { size(appwidth, appheight); background(0); myobject = new targetedobject( width / 2, height / 2, 0 ); frameRate(30); } void draw() { background(0); myobject.moveto( mouseX, mouseY ); myobject.updatedraw(); }
keynote00 keynote00 Processingcode title Key note //Get the target distance targetlength = sqrt( pow( this.mtargetx - this.mcurrentx, 2 ) + pow( this.mtargety - this.mcurrenty, 2 ) ); //Arc cosin adjacent side divide by Hypotenuse //OR arc sin subtense divide by Hypotenuse //Not using tangent to avoid Divide by Zero temprotation = acos( (this.mtargetx - this.mcurrentx) / targetlength ); //In this case, we are using cosin, so for the angle > 180 which means that //targety is under currend y if ( this.mtargety > this.mcurrenty ) { //> 180 degrees this.mrotation = temprotation; }else{ this.mrotation = 2 * PI - temprotation; } //Now that we have the rotation, we recalculate the x and y we need to travel this.mtargetx_t = (int)(this.thisstep * cos(this.mrotation)); this.mtargety_t = (int)(this.thisstep * sin(this.mrotation)); //Finally, move the object this.mcurrentx += this.mtargetx_t; this.mcurrenty += this.mtargety_t;