- HubPages»
- Technology»
- Computers & Software»
- Computer Science & Programming»
- Programming Languages
Change of coordinates in Javascript: part 3 in a series
Comments about Change of Basis
The previous article in this series covered drawing lines in Javascript. This article adds another tool, mapping of coordinates.
It often comes up that the coordinate system used on your computer screen is not the same as the coordinate system for the problem you are working on. So, there is frequently an need to map between coordinate systems in order to draw a picture of your problem.
I could have done this by writing a function that takes ten parameters, four to describe the screen coordinates, four to describe the coordinates of my problem, and two to describe the point that I want to map to the screen. However, I choose instead to store the description of the screen and problem coordinates in an object, and just pass the x and y values of the point I wish to map to a method of that object.
I used the Javascript prototype mechanism to make it possible to base other, similar objects on this one.
In the example, I drew two lines from (-1,-1) to (1,1), but varied the screen coordinates that they map to. The result is one long line starting in the lower left and rising, which is a more
conventional mapping. The second line is shorter, starts in the upper left corner and falls to the right, because in this coordinate system greater values of y map to points that are lower on the screen.
I didn't demonstrate it, but changing values of an instance of the jgcoordinates will not change the defaults for subsequent new instances.
The future examples in my series will make use of coordinate mapping. If you are interested, I
suggest playing around with this mechanism, some.
example code for changing coordinates in javascript
<html> <head> <style type="text/css" > .whiterectangle { color: white; background-color: white; z-index: 0;} .blackrectangle { color: black; background-color: black; z-index: 1;} </style> <script type="text/javascript" > var jgpointbase = { x: 0, y: 0 }; function jgpoint( ) { //this.x = x; //this.y = y; }; jgpoint.prototype = jgpointbase; function jgptsc( x, y ) { var rval = new jgpoint( ); rval.x = this.screenx0 + (( this.screenx1 - this.screenx0 ) / ( this.x1 - this.x0 )) * ( x - this.x0 ); rval.y = this.screeny0 + (( this.screeny1 - this.screeny0 ) / ( this.y1 - this.y0 )) * ( y - this.y0 ); return( rval ); } var jgcoordinatesbase = { x0: -1.25, screenx0: 50, y0: -1.25, screeny0: 450, x1: 1.25, screenx1: 450, y1: 1.25, screeny1: 50, pointToScreenCoordinates: jgptsc }; function jgcoordinates() { } jgcoordinates.prototype = jgcoordinatesbase; function drawrectangle( myclass, top, left, width, height ) { var bodylist = document.getElementsByTagName( "body" ); var rect = document.createElement( "div" ); var mystyle = 'position:absolute;top:' + top + ";left:" + left + ';width:' + width + ";height:" + height; rect.setAttribute( "class", myclass ); rect.setAttribute( "style", mystyle ); bodylist[0].appendChild( rect ); } function drawline( width, x1, y1, x2, y2 ) { var x, y, nexty, nextx; // ensure x1, y1 is leftmost point if( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; tmp = y2; y2 = y1; y1 = tmp; } var dx = x2 - x1; var dy = y2 - y1; if( dy == 0 ) { // horizontal line drawrectangle( "blackrectangle", y1 - width / 2, x1, dx, width ); return; } else if ( dx == 0 ) { // vertical line drawrectangle( "blackrectangle", y1, x1 - width / 2, width, dy ); return; } var slope = dy / dx; if( slope > 1 || slope < -1 ) { // one x per multiple y if( y1 < y2 ) { y = y1; for( x = x1 ; x < x2 ; x += 1 ) { nexty = y + slope; drawrectangle( "blackrectangle", y, x - width / 2, width, nexty - y ); y = nexty; } } else { y = y1; for( x = x1 ; x < x2 ; x += 1 ) { nexty = y + slope; drawrectangle( "blackrectangle", nexty, x - width / 2, width, y - nexty ); y = nexty; } } } else { // one y per multiple x if( y1 < y2 ){ x = x1; for( y = y1 ; y < y2 ; y += 1 ) { nextx = x + 1 / slope; drawrectangle( "blackrectangle", y - width / 2, x, nextx - x, width ); x = nextx; } } else { x = x2; for( y = y2 ; y < y1 ; y += 1 ) { nextx = x + 1 / slope; drawrectangle( "blackrectangle", y - width / 2, nextx, x - nextx, width ); x = nextx; } } } } </script> </head> <body> <script type="text/javascript" > drawrectangle( "whiterectangle", 0, 0, "100%", "100%" ); // make a background rectangle, not necessary with default browser settings var unitsquare = new jgcoordinates(); startpoint = unitsquare.pointToScreenCoordinates( -1, -1 ); endpoint = unitsquare.pointToScreenCoordinates( 1, 1 ); drawline( 4, startpoint.x, startpoint.y, endpoint.x, endpoint.y ); unitsquare.screenx0 = 0; unitsquare.screeny0 = 0; unitsquare.screenx1 = 50; unitsquare.screeny1 = 50; startpoint = unitsquare.pointToScreenCoordinates( -1, -1 ); endpoint = unitsquare.pointToScreenCoordinates( 1, 1 ); drawline( 4, startpoint.x, startpoint.y, endpoint.x, endpoint.y ); </script> </body> </html>
links to previous hubs in the series
- Learning to Program Computers on Your Own
alert( "Hello Javascript World!" ); screen-shot of firebug Firebug Open source project site for Firebug. I know you have Javascript available to you,... - Drawing a Rectangle in Javascript - part 1 in a series
Computer programming constantly uses encapsulation; someone else figures out how to do something, and you just use it without having to worry about the details. Functions are one mechanism for encapsulation,... - Drawing Lines in Javascript - part 2 in a series
My last hub showed how to draw rectangles using Javascript. This hub will make use of that capability to draw lines. There was a comment on my earlier hub about drawing rectangles in Javascript, that it...