Wednesday, December 9, 2009

Full Screen Repaint

If for any reason you have to override getWidth or getHeight methods in a class that extends Canvas, the calls to repaint() might not update the whole display.

And this is an expected behaviour. Check below documentation from API:

public final void repaint()

Requests a repaint for the entire Canvas. The effect is identical to

repaint(0, 0, getWidth(), getHeight());


If you want to always update the whole display when calling repaint() add the following method to your class:


public void repaint() {
super.repaint(0, 0, super.getWidth(), super.getHeight());
}

Tuesday, December 8, 2009

Color Distance

We can represent a color in Java ME using integer literals. The four bytes represent different aspects of the color:

  • Transparency: also known as Alpha channel. Indicates if the color should we drawn as solid or translucid

  • Red: the red component

  • Green: the green component

  • Blue: the blue component



In a previous post I pointed how to get the handset theme color dinamically with Display.getColor.
But I came to a situation where I could not use COLOR_HIGHLIGHTED_BACKGROUND with COLOR_HIGHLIGHTED_FOREGROUND.
The colors were too "close". Like dark gray over black.

My work around was to add a color distance verification. Lets imagine that the three color components are the axis of a 3D system.
To calculate the distance between two colors (two points) I just need to apply the below method:


public static int colorDistance (int c1, int c2) {
int r1 = (c1 & 0xff0000) >> 16;
int g1 = (c1 & 0x00ff00) >> 8;
int b1 = c1 & 0x0000ff;
int r2 = (c2 & 0xff0000) >> 16;
int g2 = (c2 & 0x00ff00) >> 8;
int b2 = c2 & 0x0000ff;

// http://en.wikipedia.org/wiki/Euclidean_metric
return sqrtRound(((r2 - r1) * (r2 - r1)) +
((g2 - g1) * (g2 - g1)) +
((b2 - b1) * (b2 - b1)));
}


I chose that if color distance if below or equal to 40 I should use black color for foreground and white color for background.

Related topics:

Monday, December 7, 2009

Square Root Rounding

Since CLDC 1.1 Java ME applications can use floating point operations like sin, cos, tan, sqrt, etc. All these methods are available at java.lang.Math class.

Some applications needs square root floating point precision and will have to use double variables. Other applications need only an approximation and this is what I present here.

Lets first take a look at how I create my square pyramid. To start we draw two colums with the base number and its square:








BaseSquare
00
11
24
39
416


Now we place all other numbers between the squares.








BaseSquare and other numbers
0
      values <= 0   
1
          1  2         
2
       3  4  5  6      
3
    7  8  9 10 11 12   
4
13 14 15 16 17 18 19 20


The square root approximation of these numbers is the same as the square root of the center value. For example, sqrtRound(7) == 3, sqrtRound(6) == 2.

Below is the source code:

public static int sqrtRound (int value) {
if (value <= 0) {
return 0;
}

int i = 1;
int j = 2;

// search for range where value is between two square values
while ((i * i) <= value && value > (j * j)) {
i++;
j++;
}

int d = (j * j) - (i * i) + 1;

if ((value - (i * i)) < (d / 2)) { // round down
return i;
} else { // round up
return j;
}
}