Logical Coordinates

- - - - - - - - - - - - - - - - - - - - - - - -
In this lesson we will discuss the difference between device coordinates and logical coordinates. Device coordinates are the actual pixel numbers used by Java to locate elements in an applet or canvas. Logical coordinates are a translation of device coordinates which make it easier for the programmer to locate elements in a drawing area. You may elect to stick to using device coordinates, or you may decide that you prefer working with logical coordinates. More on this in a little bit.

The Java Abstract Windows Toolkit (AWT) provides the class Graphics which contains a number of draw methods. We will use the drawLine and the drawRect methods to explore the difference between device coordinates and logical coordinates. We will also use the Canvas class to contain our drawing area.

Device Coordinates:
The smallest area for which we can set the color for on the screen is a pixel (short for picture elements). Each picture can be addressed using integer values which represent the x- and y-coordinates. The upper, left corner of the drawing area is (0,0) and the lower, right corner is (width,height). This way of descriping the location of a pixel is referred to as device coordinates. Here is a line which will fill in a single pixel:

  g.drawRect(x,y,1,1);
Here's an applet which draws a diagonal line using device coordinates. import java.awt.*; import java.applet.*; public class diagonal1 extends Applet{ public void init(){ setBackground(Color.white); setLayout(new BorderLayout()); add("Center", new D1()); } } class D1 extends Canvas{ public void paint(Graphics g){ Dimension d = getSize(); int maxX = d.width -1, maxY = d.height -1; g.setColor(Color.red); g.drawLine(0,maxY,maxX,0); } } //<applet code=diagonal1.class height=100 width=200></applet>
Logical Coordinates:
From the point of view of the programmer, the y-coordinates are mapped in a counter-intuitive fashion. That is, we would expect the values to increase as we go up, or, more precisely, we would like (0,0) to represent the lower, left corner of the draw area and (maxX, MaxY) to represent the upper,right corner of the draw area. We can create a conversion method which allows us to use logical coordinates so that we can think "logically" and still keep the compiler/programming environment happy with the device coordinates which it prefers. Since the x-coordinates already operate in a logical fashion, we only need to write a special method to convert y-coordinates. Here's the method:
  int logicalY(int y){ return maxY - y; }
Here's a sample applet which uses logical coordinates: import java.awt.*; import java.applet.*; public class diagonal2 extends Applet{ public void init(){ setBackground(Color.white); setLayout(new BorderLayout()); add("Center", new D2()); } } class D2 extends Canvas{ int maxY; public void paint(Graphics g){ Dimension d = getSize(); int maxX = d.width -1; int top = maxY = d.height -1; g.setColor(Color.red); g.drawLine(0,logicalY(0),maxX,logicalY(top)); } int logicalY(int y){ return maxY - y; } } //<applet code=diagonal2.class height=100 width=200></applet> In order to do the assignment you will need to understand the following applet: import java.awt.*; import java.applet.*; public class Triangle extends Applet{ public void init(){ setBackground(Color.white); setLayout(new BorderLayout()); add("Center", new CvTriangles() ); } } class CvTriangles extends Canvas{ int maxX, maxY, minMaxXY, xCenter, yCenter; void initgr(){ Dimension d = getSize(); maxX = d.width -1; maxY = d.height -1; minMaxXY = Math.min(maxX, maxY); xCenter = maxX/2; yCenter = maxY/2; } int iX(float x){return Math.round(x);} int iY(float y){return maxY - Math.round(y);} public void paint(Graphics g){ initgr(); float side = 0.95F * minMaxXY, sideHalf = 0.5F * side, h = sideHalf * (float)Math.sqrt(3), xA, yA, xB, yB, xC, yC, xA1, yA1, xB1, yB1, xC1, yC1, p, q; q = 0.05F; p = 1 -q; xA = xCenter - sideHalf; yA = yCenter - 0.5F * h; xB = xCenter + sideHalf; yB = yA; xC = xCenter; yC = yCenter + 0.5F * h; for(int i = 0; i<50; i++){ g.drawLine(iX(xA), iY(yA), iX(xB), iY(yB)); g.drawLine(iX(xB), iY(yB), iX(xC), iY(yC)); g.drawLine(iX(xC), iY(yC), iX(xA), iY(yA)); xA1 = p * xA + q * xB; yA1 = p * yA + q * yB; xB1 = p * xB + q * xC; yB1 = p * yB + q * yC; xC1 = p * xC + q * xA; yC1 = p * yC + q * yA; xA = xA1; xB = xB1; xC = xC1; yA = yA1; yB = yB1; yC = yC1; } } } //<applet code=Triangle.java width=300 height=300></applet>
- - - - - - - - - - - - - - - - - - - - - - - -
ASSIGNMENT:
Building on what you learned through inspection of the Triangle applet. Create the following applet: