Unexpected Character Movement

I am developing a sketch to graphically display GPS data coming from an Arduino. The sketch paints the background and “gauge” bezel and then calls various functions to fill in the face with appropriate data,
.
The compass function paint dots for 5 degree gradations in a circle inside the bezel. Following the dots the directional characters are displayed in a circle around the dots. Finally a pointer is painted.

The first time through the function, all is well. The second time through the function nothing changes except the directional characters are placed about 1/2" higher on the screen. I have printed out the x and y coordinates for each character each time through the function and they do not change yet the image has moved. All other parts of the screen remain in their original position.

Subsequent calls to the function cause no change (the original characters are misplaced on the screen). The clock function behaves the very same way.

I am attaching an document that shows the results of the printing.

Screen images of the before and after are attached:


My code for the compass function:

void Analog_Compass (){
int h,i;
String Directions [] = {"S","SW","W","NW","N","NE","E","SE"};
float needle_length = GD_IR * .5* 1.35;                     
float adjustments[] = {1.37, 1.45, 1.48, 1.45, 1.55, 1.50, 1.55, 1.50, 1.50, 1.48, 1.45, 1.45};        
int w = 0; 
int mindots [] = {8,8,7,5,5,5,4,4};
int hrdots [] = {15,15,13,10,10,10,8,8};
Compass_Calls ++;
//if (Compass_Calls == 2)  exit();
//println ("Calls to 'Compass' with: "  +nf(Current_Direction,0,1));

//.................   Clear the face if using the daytime colors and establish the colors for the dots and numerals
if (SS_OnOff[10] == false){
     fill (white);
     stroke(white);
     strokeWeight(0);
     ellipse (GD_CX[Compass],GD_CY[Compass],GD_IR*2, GD_IR*2);
     fill (black);
     stroke(black);
} else { 
     fill (black);
     stroke(black);
     strokeWeight(0);     
     ellipse (GD_CX[Compass],GD_CY[Compass],GD_IR*2, GD_IR*2);
     fill (blue);
     stroke(blue);
}

//.........................  Paint a dot every 5 degrees around the face of the compass
float dot_distance = GD_IR * .5* 1.35;
beginShape(POINTS);
    for (float a = 0; a <= 360; a+=5) {
        float angle = radians(a)+HALF_PI;
        float x1 = GD_CX[Compass] + cos(angle) * dot_distance;
        float y1 = GD_CY[Compass] + sin(angle) * dot_distance;
        if (a%45 == 0) strokeWeight(hrdots[GD_Active]); else strokeWeight(mindots[GD_Active]);
        vertex(x1, y1);
    }
endShape();

//..........................   Paint the compass directions on the face of the compass 
w = 0;
for (int a = 0; a < 360; a+=45) {
    if (a%90 == 0) textSize(GD_IR *.32); else  textSize(GD_IR *.22);
    float angle = radians(a)+HALF_PI;
    float adjusted_radius = (GD_IR * .58) * adjustments[w];
    float x2 = GD_CX[Compass] + cos(angle) * adjusted_radius;
    float y2 = GD_CY[Compass] + sin(angle) * adjusted_radius;
    text (Directions[w],x2,y2);
   // println (w + "  '" + Directions[w] + "' at " + x2 + "/" + y2);
    w = w+1;
}


//.........................  Paint the compass needle
Needle (Compass,map(int(Current_Direction), 0, 360, 0, TWO_PI) - HALF_PI, needle_length * .93);

}//........................  End of analog compass

1 Like

I dont see the Needle() function. Are you using translate() or rotate() inside it?

UPDATED! Some essential code was missing!

Hello,

I did not find the root of your problem.
I suggest simplifying and try to isolate.
Try push() and pop() in places.

Your code did inspire me to find a simple way to align text and learned something in the process!
Making a compass for my sensor is on my to-do list. :slight_smile:

Modified code (click with mouse to see alignment):

int w;
boolean toggle = false;
float x2, y2;

void setup() 
	{
  size(400, 400);
	}

void draw() 
	{
  background(0);
  translate(width/2, height/2);
  Analog_Compass();
	}

void Analog_Compass ()
  {
  String Directions [] = {"S", "SW", "W", "NW", "N", "NE", "E", "SE"};
  stroke(255, 255, 0);      
  w=0;
  for (int a = 0; a < 360; a += 45) 
    {
    if (a%90 == 0) 
      textSize(36); 
    else  
      textSize(24);
    
    textAlign(CENTER, BASELINE);
    fill(0, 255, 0);

    float angle = radians(a) + HALF_PI;
    if (toggle)
      {
      x2 = cos(angle) * 100;
      y2 = sin(angle) * 100;
      }
    else
      {
      x2 = cos(angle) * 130;
      y2 = sin(angle) * 130;
      }
    
    text(Directions[w], x2, y2-(textDescent()-textAscent())/2); //calculated
    //text (Directions[w], x2, y2 + 36.0/2 - 5 ); //manual align
    //text (Directions[w], x2, y2 + 24.0/2 - 4);  //manual align
    w++;
    println(w);
    println(textDescent(), textAscent(), textDescent()-textAscent(), (textDescent()-textAscent())/2);
    }
    
  for (float a = 0; a <= 360; a+=360.0/16) 
    {
    float angle = radians(a) + HALF_PI;
    float x1 = cos(angle) * 100;
    float y1 = sin(angle) * 100;
    strokeWeight(6);
    point(x1, y1);
    }   
  }
  
void mousePressed()
  {
  toggle = !toggle;
  }
  

image image

:slight_smile:

2 Likes

Neither. The area where the needle is cleared each time so I simply redraw the needle. As you probably suspect, I am new to Processing and Java for that matter. I wanted a needle that looked like a needle and not a straight line. The only way that I knew how to do that was to make the needle out of straight lines of different length.

Thank you for responding!

I made a sketch out of the code you sent me and all i have is a postage stamp sized window that does nothing that I could see. Whats missing here?

I finally discovered the cause of my problem: incorrectly formed “textAlign” statement.
The responses I received have shown me that there are better ways to do things and for that, I thank you.

2 Likes

Hello,

I updated the code I posted:

:slight_smile:

Happy New Year,
I ran you code and it is working just fine. What I am particularly interested in is the following:

  text(Directions[w], x2, y2-(textDescent()-textAscent())/2); //calculated

I believe that I understand the concept of text decent and text ascent. But your usage here has me scratching my head. I know it works because I can see it. You use the ascent/descent to modify the Y axis but you don’t modify the X axis. Your method is much better than mine so I am changing my compass and clock coding to use your method. I need to work at it a little.
Thank you again.

Happy New Year!

This may help:

// GLV
// Text Alignment Exploration
// 2020-01-01

float x;

void setup() 
	{
  size(1000, 500);
	}

void draw() 
	{
  background(0);
  translate(0, height/2);
  
  x = map(mouseX, 0, width, 1, 3);
  
  textSize(x*48);
  textAlign(CENTER, BASELINE);
  
  strokeWeight(2);
  stroke(255, 255, 0);
  line (0, 0, width, 0);
  
  stroke(255, 0, 0);
  line (0, -textAscent(), width, -textAscent());
  
  stroke(0, 255, 0);
  line (0, textDescent(), width, textDescent());
  
  float diff = textDescent() - textAscent();
  stroke(100);
  line (0, diff/2, width, diff/2);
  line (0, -diff/2, width, -diff/2);  
  
  println(textAscent(), textDescent(), diff);
 
  textAlign(CENTER, BASELINE);
  text("Bb", 1*width/6, 0);
  
  textAlign(CENTER, BASELINE);
  text("Bb", 2*width/6, -diff/2);
  
  textAlign(CENTER, CENTER);
  text("Bb", 3*width/6, -textDescent()/2);
  
  textAlign(CENTER, TOP);
  text("Bb", 4*width/6, -textAscent()-diff/2);
  
  textAlign(CENTER, BOTTOM);
  text("Bb", 5*width/6, +textDescent()-diff/2);
	}

It helped me!

:slight_smile:

1 Like

I rewrote my clock and compass logic to position the various characters according to your idea. I removed all adjustment calculations and moved the radius calculation outside of the “for” loop. The results were terrific. The numbers on the clock and the letters on the compass were right on. My sketch allows for up to 7 gauges to be displayed. Of course the more gauges on the screen means the gauges have to be re scaled each time a gauge is added or removed. I think this is begging for push/pop matrix and translate (all new to me) but I will work on it.

Thank you again for your help.

2 Likes