-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
cartesian_to_polar.c
123 lines (114 loc) · 2.56 KB
/
cartesian_to_polar.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @file
* @brief Function to convert a Cartesian co-ordinate to polar form.
*/
#define _USE_MATH_DEFINES /**< required for MS Visual C */
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Function to convert cartesian coordinates to polar.
*\f{eqnarray*}{
r &=& \sqrt{x^2+y^2}\\
\theta &=& \atan\frac{y}{x}
\f}
* @param [in] x absicca value
* @param [in] y ordinate value
* @param [out] r pointer to store polar radius
* @param [out] theta pointer to store polar angle (in radian)
*/
void to_polar(double x, double y, double *r, double *theta)
{
double thetaFinal = 0.f;
*r = sqrt(x * x + y * y);
if (x != 0)
{
if (y != 0)
{
*theta = atan(y / x);
if ((x > 0 && y > 0) || (x == -y))
{ // Q1
thetaFinal = *theta;
}
else if (x < 0 && y > 0)
{ // Q2
thetaFinal = *theta + M_PI;
}
else if (x < 0 && y < 0)
{ // Q3
thetaFinal = *theta - M_PI;
}
else if (x > 0 && y < 0)
{ // Q4
thetaFinal = 2 * M_PI - *theta;
}
else
{
fprintf(stderr, "Should not reach here!\n");
}
}
}
else
{ // exceptions when no actual angle is present
if (y > 0)
{
thetaFinal = M_PI / 2;
}
else
{
thetaFinal = -(M_PI / 2);
}
}
if (y == 0)
{
if (x > 0)
{
thetaFinal = 0;
}
else
{
thetaFinal = -M_PI;
}
}
*theta = thetaFinal;
}
/**
* @brief Generate a random number in the given limits
*
* @param lim1 lower limit
* @param lim2 upper limit
* @return random number in the given range
*/
double get_rand(double lim1, double lim2)
{
double r = (double)rand() / RAND_MAX; // value in [0,1)
return (lim2 - lim1) * r + lim1; // scale to range
}
/**
* @brief Test implementation
*
*/
void test()
{
srand(10);
int NUM_TESTS = 5;
for (int i = 0; i < NUM_TESTS; i++)
{
double r, theta;
printf("Test %d.... ", i);
double x = get_rand(-5, 5);
double y = get_rand(-5, 5);
printf("(%.2g, %.2g).... ", x, y);
to_polar(x, y, &r, &theta);
assert(fabs(r - hypot(x, y)) < 0.01);
assert(fabs(theta - atan2(y, x)) < 0.01);
printf("passed\n");
}
}
/** Main function */
int main()
{
test();
return 0;
}