Go Down

### Topic: Draw and Erase (Read 984 times)previous topic - next topic

##### Dec 02, 2011, 05:08 pm
Hello all,

I have a question with regard to the code below. What I am trying to do is this -

1. draw an arrow with the given co-ordinates and angle,
2. increment angle in the main for loop,
3. erase the old arrow if the angke has changed and then sraw the new one.

however, this code seems to work only for the first two times. for example, if I set i = 0 and increment by 5, the erase IF works only for 0 and 5. All other values of i seem to ignore the IF condition.

Any help with this would be greatly appreciated.

Thank you,

Code: [Select]
`#include <T6963.h>T6963 lcd(240, 128, 6, 32);int x0, y0, arrowHeight, arrowWidth, i;void setup(){  Serial.begin(9600);  lcd.Initialize();  lcd.clearGraphic();}void loop(){  for(i = 0; i <= 360; i += 5)  {    createArrow(118, 64, 60, 20, i);    delay(30000);  }}void createArrow(int x0, int y0, int arrowHeight, int arrowWidth, int angle){  int x1, x2, y1, y2, x3, y3;  int x0_old;  int x1_old;  int x2_old;    int x3_old;  int y0_old;  int y1_old;  int y2_old;    int y3_old;    int old_angle = 0;  x1 = x0 + arrowWidth;  y1 = y0;  x2 = x0 + (arrowWidth / 2);  y2 = abs(y0 - arrowHeight);  x3 = x2;  y3 = y0 - 10;  x0_old = x0;  x1_old = x1;  x2_old = x2;    x3_old = x3;  y0_old = y0;  y1_old = y1;  y2_old = y2;  y3_old = y3;  if((angle - old_angle) > 0)  {    old_angle = angle;    lcd.createLine(x1_old, y1_old, x2_old, y2_old, 0);    lcd.createLine(x0_old, y0_old, x2_old, y2_old, 0);      lcd.createLine(x0_old, y0_old, x3_old, y3_old, 0);    lcd.createLine(x1_old, y1_old, x3_old, y3_old, 0);      }  Serial.print(angle, DEC);  Serial.print("  ");  Serial.println(old_angle, DEC);     float theta = angle*(3.1415/180);  int cx_x0, cy_y0, cx_x1, cy_y1, cx_x2, cy_y2, cx_x3, cy_y3;  int x_ref = ((x0 + x1 + x2)/3);  int y_ref = ((y0 + y1 + y2)/3);   cx_x0 = x0 - x_ref;  cy_y0 = y0 - y_ref;  cx_x1 = x1 - x_ref;  cy_y1 = y1 - y_ref;  cx_x2 = x2 - x_ref;  cy_y2 = y2 - y_ref;  cx_x3 = x3 - x_ref;  cy_y3 = y3 - y_ref;  x0= x_ref - ((int)(cx_x0*cos(theta)))-((int)(cy_y0* sin(theta)));  y0= y_ref - ((int)(cx_x0*sin(theta)))+((int)(cy_y0* cos(theta)));   x1= x_ref - ((int)(cx_x1*cos(theta)))-((int)(cy_y1* sin(theta)));  y1= y_ref - ((int)(cx_x1*sin(theta)))+((int)(cy_y1* cos(theta)));   x2= x_ref - ((int)(cx_x2*cos(theta)))-((int)(cy_y2* sin(theta)));  y2= y_ref - ((int)(cx_x2*sin(theta)))+((int)(cy_y2* cos(theta)));  x3= x_ref - ((int)(cx_x3*cos(theta)))-((int)(cy_y3* sin(theta)));  y3= y_ref - ((int)(cx_x3*sin(theta)))+((int)(cy_y3* cos(theta)));    lcd.createLine(x1, y1, x2, y2, 1);  lcd.createLine(x0, y0, x2, y2, 1);    lcd.createLine(x0, y0, x3, y3, 1);  lcd.createLine(x1, y1, x3, y3, 1);  }`

#### robtillaart

#1
##### Dec 02, 2011, 09:34 pm
old_angle is a local var of the function and is reinitialized every time the function is called.

You must declare the old_XXX vars outside the function OR as a static int

Why not creat a simpler function with one extra parameter DRAW = 1 or ERASE=0 (#defines? )

(code not tested but give it a try)
Code: [Select]
`#include <T6963.h>T6963 lcd(240, 128, 6, 32);int x0, y0, arrowHeight, arrowWidth, i;void setup(){  Serial.begin(9600);  lcd.Initialize();  lcd.clearGraphic();}void loop(){  for(i = 0; i <= 360; i += 5)  {    createArrow(118, 64, 60, 20, i, 1); // additional parameter to draw =1    delay(30000);    createArrow(118, 64, 60, 20, i, 0); // and now erase=0 the same line  }}void createArrow(int x0, int y0, int arrowHeight, int arrowWidth, int angle, int drawmode){  int x1, x2, y1, y2, x3, y3;  x1 = x0 + arrowWidth;  y1 = y0;  x2 = x0 + (arrowWidth / 2);  y2 = abs(y0 - arrowHeight);  x3 = x2;  y3 = y0 - 10;  int cx_x0, cy_y0, cx_x1, cy_y1, cx_x2, cy_y2, cx_x3, cy_y3;  int x_ref = ((x0 + x1 + x2)/3);  int y_ref = ((y0 + y1 + y2)/3);   cx_x0 = x0 - x_ref;  cy_y0 = y0 - y_ref;  cx_x1 = x1 - x_ref;  cy_y1 = y1 - y_ref;  cx_x2 = x2 - x_ref;  cy_y2 = y2 - y_ref;  cx_x3 = x3 - x_ref;  cy_y3 = y3 - y_ref;  float theta = angle * 0.017453293;  // PI/180 optimization  float costh = cos(theta); // optimization no need to recalculate 8 times  float sinth = sin(theta);  x0 = x_ref - (int)(cx_x0 * costh - cy_y0 * sinth);   y0 = y_ref - (int)(cx_x0 * sinth + cy_y0 * costh);   x1 = x_ref - (int)(cx_x1 * costh - cy_y1 * sinth);   y1 = y_ref - (int)(cx_x1 * sinth + cy_y1 * costh);   x2 = x_ref - (int)(cx_x2 * costh - cy_y2 * sinth);   y2 = y_ref - (int)(cx_x2 * sinth + cy_y2 * costh);   x3 = x_ref - (int)(cx_x3 * costh - cy_y3 * sinth);   y3 = y_ref - (int)(cx_x3 * sinth + cy_y3 * costh);   lcd.createLine(x1, y1, x2, y2, drawmode);  lcd.createLine(x0, y0, x2, y2, drawmode);    lcd.createLine(x0, y0, x3, y3, drawmode);  lcd.createLine(x1, y1, x3, y3, drawmode);  }`
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### PaulS

#2
##### Dec 02, 2011, 09:36 pm
You are the only one that can see the debug output. Does it show proper values.

Some comments would be useful.

Quote
All other values of i seem to ignore the IF condition.

Not likely. You need to explain what is actually happening.

As a test, try changing the start value of the for loop to something other than 0. Try 37, for instance. Does that change the behavior of the program? That is, is the first arrow drawn and then erased correctly, regardless of the starting angle?
The art of getting good answers lies in asking good questions.

#3
##### Dec 02, 2011, 11:22 pm
Hello all,

Thank you so much for replying. Please find my answers to your questions below:

Quote
As a test, try changing the start value of the for loop to something other than 0. Try 37, for instance. Does that change the behavior of the program? That is, is the first arrow drawn and then erased correctly, regardless of the starting angle?

I tried this and no, the erase function seems to work only for 'i' values of 0 and 5 for some reason. Any other value is ignored.

Quote
(code not tested but give it a try)

This works! However, it seems to think 0 degrees is pointing bottom rather than on top. I shall post again after I see what I have done.

Again, thank you all once again.

Regards,

#4
##### Dec 02, 2011, 11:51 pm
Hello all,

Here is an update to the below:

Quote
This works! However, it seems to think 0 degrees is pointing bottom rather than on top. I shall post again after I see what I have
done.

I changed the following from robtillaart's code posting:

Code: [Select]
`  x0 = x_ref - (int)(cx_x0 * costh - cy_y0 * sinth);   y0 = y_ref - (int)(cx_x0 * sinth + cy_y0 * costh);   x1 = x_ref - (int)(cx_x1 * costh - cy_y1 * sinth);   y1 = y_ref - (int)(cx_x1 * sinth + cy_y1 * costh);   x2 = x_ref - (int)(cx_x2 * costh - cy_y2 * sinth);   y2 = y_ref - (int)(cx_x2 * sinth + cy_y2 * costh);   x3 = x_ref - (int)(cx_x3 * costh - cy_y3 * sinth);   y3 = y_ref - (int)(cx_x3 * sinth + cy_y3 * costh);`

To...

Code: [Select]
`  x0 = x_ref - (int)(cx_x0 * costh) - (int)(cy_y0 * sinth);   y0 = y_ref - (int)(cx_x0 * sinth) + (int)(cy_y0 * costh);    x1 = x_ref - (int)(cx_x1 * costh) - (int)(cy_y1 * sinth);   y1 = y_ref - (int)(cx_x1 * sinth) + (int)(cy_y1 * costh);     x2 = x_ref - (int)(cx_x2 * costh) - (int)(cy_y2 * sinth);   y2 = y_ref - (int)(cx_x2 * sinth) + (int)(cy_y2 * costh);     x3 = x_ref - (int)(cx_x3 * costh) - (int)(cy_y3 * sinth);   y3 = y_ref - (int)(cx_x3 * sinth) + (int)(cy_y3 * costh);`

Now the arrow seems to be pointing in the right direction. Can anyone please help me understand the difference between the two pieces of code?

#### robtillaart

#5
##### Dec 03, 2011, 04:04 pm

Quote
Can anyone please help me understand the difference between the two pieces of code?

I "optimized" too much parenthesis away, sorry
The best way to understand the code is too take paper and pencil and write out every step as if you were the CPU. Be sure to write every answer of every addition/subtraction/mult/sin/etc and you wil see the diff.

I assume it is in the casting which throws away the decimal part.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up