0

I am trying to divide the circle into n equal parts using straight lines. Idea is to get the coordinates of the end points on the circumference of the circle and then to draw the line.

to find coodrinates I am using following code:

static void getPoints(int x0,int y0,int r)
{

   double angle = 0;
   double angleToRadian = 0;

   for(int i = 0 ; i < noOfDividingPoints  ;i++)
   {   
      angle = i * (360/noOfDividingPoints);

      angleToRadian = ( angle * 3.141 ) / 180;

      APP_LOG(APP_LOG_LEVEL_DEBUG, "LOG: Angle: %lf, AngleToRadian: %lf", angle, angleToRadian );

      x[i] = (int) (x0 + r * cos_lookup(angleToRadian));
      y[i] = (int) (y0 + r * sin_lookup(angleToRadian));
      APP_LOG(APP_LOG_LEVEL_DEBUG, "LOG: i: %d,  x[i]: %d, y[i]: %d", i, (int)x[i], (int)y[i] );
   }
}

Using this getPoints method I am filling the array x[] and y[] and then iterate over these arrays to draw lines between x[i] and y[i]

However, the values calculated from the above code comes out to be weird, below are the logs printing the contents of x[] and y[]

[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f

[14:18:57] WatchFace.c:45> LOG: i: 0,  x[i]: 4587522, y[i]: 84
[14:18:57] WatchFace.c:36> LOG: Angle: 90
[14:18:57] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 1,  x[i]: 4587522, y[i]: 84
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 2,  x[i]: 4587452, y[i]: 504
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 3,  x[i]: 4587452, y[i]: 924
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 4,  x[i]: 4587452, y[i]: 1344
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 5,  x[i]: 4587452, y[i]: 1344
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 6,  x[i]: 4587452, y[i]: 1834
[14:18:58] WatchFace.c:36> LOG: Angle: 90
[14:18:58] WatchFace.c:41> LOG: Angle: f, AngleToRadian: f
[14:18:58] WatchFace.c:45> LOG: i: 7,  x[i]: 4587452, y[i]: 2254

Please point out what I am missing here.

Thanks.

blackbug
  • 1,098
  • 3
  • 13
  • 40
  • Could you also log the values of x0, y0, and r at the beginning of the function? I'd like to see what they are. – Kevin Jan 05 '16 at 14:07
  • @Kevin x0, y0 and r are coodinates of the center and radius respectively. They doesnt change. Since I am doing this on pebble watch, the center of circle is the center of the screen wic is calc as (x,y) = ( bounds.size.w / 2, bounds.size.h / 2 ) and radius is 70. – blackbug Jan 05 '16 at 14:23
  • Ok, but if x0 is `4587450` when you expect it to be `1234`, this would explain your strange x values. That's why it's worth investigating. – Kevin Jan 05 '16 at 14:24
  • By the way, what is the value of `noOfDividingPoints`? – Kevin Jan 05 '16 at 14:25
  • It appears that the code you provided is inconsistent with the logs that you provided. In your logs you have the line "[14:18:58] WatchFace.c:36> LOG: Angle: 90", yet I can't see where in the code that output is produced. Also, what is the type of `noOfDividingPoints`? – thurizas Jan 05 '16 at 14:28
  • noOfDividingPoints is the number into wic we want to divide the circle, here its 8. – blackbug Jan 05 '16 at 14:29

2 Answers2

3

The lookup-functions for sine and cosine in Pebble don't take the angle in radians or degrees; they use an integer angle normalized to TRIG_MAX_ANGLE, which corresponds to a full circle or 360°.

The same applies to the returned value, which is a signed int that must be normalized with TRIG_MAX_RATIO to get a valid cosine or sine.

So you should be able to do something like this.

for (int i = 0; i < n ; i++) {
    int32_t angle = i * TRIG_MAX_ANGLE / n;

    x[i] = x0 + (r * cos_lookup(angle)) / TRIG_MAX_RATIO;
    y[i] = y0 + (r * sin_lookup(angle)) / TRIG_MAX_RATIO;
}

Note that all calculations are done with integers. Take care to multiply first and then divide, so that you don't truncate results. For example,

cos_lookup(angle) / TRIG_MAX_RATIO

will always yield zero, except when the angle corresponds to 0° or 180°.

You also might want to have a look at the clock hand example on the page linked above.

M Oehm
  • 28,726
  • 3
  • 31
  • 42
1

You do a division of int by int and store the result to a double. You have to convert to double first, before you do the division.

angle = i * (360.0/noOfDividingPoints);
             // ^^ now it is a floting point division
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • thanks for the ans, however, I have already tried it. I forget to paste the modified code. I casted the variables explicitly but still same result. – blackbug Jan 05 '16 at 14:22