Pointers changing eachother despite being unrelated - arrays

I am trying to use the Simplex Downhill method for finding the minimum of a function. I take three points as arrays of two values and assign each a pointer so that I can order them high-to-low according to their output of some function (Rosenbrock's parabolic valley in this case). After ordering these pointers I attempt to update the arrays with the respective values, however both the high and medium point take the same value unless the points were already in the correct order.
I set the three arrays and their respective pointers,
double plarray[] = {0., 0.};
double pmarray[] = {2., 0.};
double pharray[] = {0., 2.};
double *pl, *pm, *ph;
pl = &plarray[0], pm = &pmarray[0], ph = &pharray[0];
and sort the pointers as above. This bit works well, however when I try to replace the arrays with the proper values using this function,
void update(double x[], double *y){
x[0] = *y;
x[1] = *(y+1);
}
both pmarray and pharray take on the same values. I've tried swapping them around but it doesn't seem to change anything. Interestingly, plarray seems to work perfectly fine regardless of update order.
Brop (array of pointers sorted from lowest to highest in terms of their Brock output) is sorted as such where brockop points to Brock. sortSize sorts the pointers given by the given function,
brop = sortSize(pl, pm, ph, brockop);
double ** sortSize(double * p1p, double * p2p, double * p3p, double (func)(double *)){
static double * order[3];
double bp1 = func(p1p);
double bp2 = func(p2p);
double bp3 = func(p3p);
double brocks[] = {bp1, bp2, bp3};
order[2] = ((bp1 > bp2 && bp1 > bp3)? p1p: (bp2 > bp3)? p2p:p3p);
order[0] = ((bp1 < bp2 && bp1 < bp3)? p1p: (bp2 < bp3)? p2p:p3p);
order[1] = ((bp1 != func(order[0]) && bp1 != func(order[2]))? p1p: (bp2 != func(order[0]) && bp2 != func(order[2]))? p2p: p3p);
return order;
}
I then assign the pointers to the sorted values in brop,
pl = *brop;
pm = *(brop + 1);
ph = *(brop + 2);
Please note that brop is an array of the pointers to the points of the function I wanted to sort, not a point itself.
I have some output after adding a bunch of printf for debugging,
y of Brop[0], (0.000000, 0.000000) = 1.000000
y of Brop[1], (-1.000000, 1.500000) = 29.000000
y of Brop[2], (0.000000, 2.000000) = 401.000000
--------Before assigning to Brop values--------
P_h pointer: -1.000000, 1.500000, yh = 29.000000
P_m pointer: 0.000000, 2.000000, ym = 401.000000
P_l pointer: 0.000000, 0.000000, yl = 1.000000
--------Array values before assigning to brop ------
P_h array: -1.000000, 1.500000, yh = 29.000000
P_m array: 0.000000, 2.000000, ym = 401.000000
P_l array: 0.000000, 0.000000, yl = 1.000000
-------Pointers asigned to brop values-----
P_h pointer: 0.000000, 2.000000, yh = 401.000000
P_m pointer: -1.000000, 1.500000, ym = 29.000000
P_l pointer: 0.000000, 0.000000, yl = 1.000000
--------Array values after assigning to brop-------
P_h array: -1.000000, 1.500000, yh = 29.000000
P_m array: 0.000000, 2.000000, ym = 401.000000
P_l array: 0.000000, 0.000000, yl = 1.000000
------------P_m updated--------
P_h pointer: -1.000000, 1.500000, yh = 29.000000
P_m pointer: -1.000000, 1.500000, ym = 29.000000
P_l pointer: 0.000000, 0.000000, yl = 1.000000
------------P_h updated--------
P_h pointer: -1.000000, 1.500000, yh = 29.000000
P_m pointer: -1.000000, 1.500000, ym = 29.000000
P_l pointer: 0.000000, 0.000000, yl = 1.000000
----------Arrays updated-----------
P_h: -1.000000, 1.500000, yh = 29.000000
P_m: -1.000000, 1.500000, ym = 29.000000
P_l: 0.000000, 0.000000, yl = 1.000000
Code used to produce debug output:
printf("--------Before assigning to Brop values--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("--------Array values before assigning to brop ------\n");
printf("P_h array: %lf, %lf, yh = %lf\n", pharray[0], pharray[1], BrockNP(pharray));
printf("P_m array: %lf, %lf, ym = %lf\n", pmarray[0], pmarray[1], BrockNP(pmarray));
printf("P_l array: %lf, %lf, yl = %lf\n", plarray[0], plarray[1], BrockNP(plarray));
pl = *brop;
pm = *(brop + 1);
ph = *(brop + 2);
printf("-------Pointers asigned to brop values-----\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("--------Array values after assigning to brop-------\n");
printf("P_h array: %lf, %lf, yh = %lf\n", pharray[0], pharray[1], BrockNP(pharray));
printf("P_m array: %lf, %lf, ym = %lf\n", pmarray[0], pmarray[1], BrockNP(pmarray));
printf("P_l array: %lf, %lf, yl = %lf\n", plarray[0], plarray[1], BrockNP(plarray));
update(pmarray, *(brop + 1));
printf("------------P_m updated--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
update(pharray, *(brop+2));
printf("------------P_h updated--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
update(plarray, *brop);
printf("----------Arrays updated-----------\n");
printf("P_h: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("after sorting\n");
Function used for y-values:
double Brock(double * vec){
return 100*pow(*(vec+1) - ((*vec)*(*vec)), 2) + pow(1 - *vec, 2);
}
Minimal Reproducible Example:
#include <stdio.h>
#include <math.h>
double BrockNP(double x[]){
return 100*pow(x[1] - (x[0]*x[0]), 2) + pow(1 - x[0], 2);
}
double Brock(double * vec){
return 100*pow(*(vec+1) - ((*vec)*(*vec)), 2) + pow(1 - *vec, 2);
}
double ** sortSize(double * p1p, double * p2p, double * p3p, double (func)(double *));
void update(double x[], double *y);
int main(){
double *pl, *pm, *ph;
double **brop;
double (*brockop)(double *);
double plarray[] = {0., 0.};
double pmarray[] = {2., 0.};
double pharray[] = {0., 2.};
pl = &plarray[0], pm = &pmarray[0], ph = &pharray[0];
brockop = &Brock;
brop = sortSize(pl, pm, ph, brockop);
printf("--------Before assigning to Brop values--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("--------Array values before assigning to brop ------\n");
printf("P_h array: %lf, %lf, yh = %lf\n", pharray[0], pharray[1], BrockNP(pharray));
printf("P_m array: %lf, %lf, ym = %lf\n", pmarray[0], pmarray[1], BrockNP(pmarray));
printf("P_l array: %lf, %lf, yl = %lf\n", plarray[0], plarray[1], BrockNP(plarray));
pl = *brop;
pm = *(brop + 1);
ph = *(brop + 2);
printf("-------Pointers asigned to brop values-----\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("--------Array values after assigning to brop-------\n");
printf("P_h array: %lf, %lf, yh = %lf\n", pharray[0], pharray[1], BrockNP(pharray));
printf("P_m array: %lf, %lf, ym = %lf\n", pmarray[0], pmarray[1], BrockNP(pmarray));
printf("P_l array: %lf, %lf, yl = %lf\n", plarray[0], plarray[1], BrockNP(plarray));
update(pmarray, *(brop + 1)); //This seems to set pharray and pmarray to the same array
printf("------------P_m updated--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
update(pharray, *(brop+2));
printf("------------P_h updated--------\n");
printf("P_h pointer: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m pointer: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l pointer: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
update(plarray, *brop);
printf("----------Arrays updated-----------\n");
printf("P_h: %lf, %lf, yh = %lf\n", *ph, *(ph+1), Brock(ph));
printf("P_m: %lf, %lf, ym = %lf\n", *pm, *(pm+1), Brock(pm));
printf("P_l: %lf, %lf, yl = %lf\n", *pl, *(pl+1), Brock(pl));
printf("after sorting\n");
return 0;
}
double ** sortSize(double * p1p, double * p2p, double * p3p, double (func)(double *)){
static double * order[3];
double bp1 = func(p1p);
double bp2 = func(p2p);
double bp3 = func(p3p);
double brocks[] = {bp1, bp2, bp3};
order[2] = ((bp1 > bp2 && bp1 > bp3)? p1p: (bp2 > bp3)? p2p:p3p);
order[0] = ((bp1 < bp2 && bp1 < bp3)? p1p: (bp2 < bp3)? p2p:p3p);
order[1] = ((bp1 != func(order[0]) && bp1 != func(order[2]))? p1p: (bp2 != func(order[0]) && bp2 != func(order[2]))? p2p: p3p);
return order;
}
void update(double x[], double *y){
x[0] = *y;
x[1] = *(y+1);
}
Any help would be much appreciated.
Edit: brop is just the array of pointers in size order as above.

If we simplify your code down to the absolute minimum (using just two doubles instead of three arrays), you'll see that you do the equivalent of this:
double x = 42, y = 43;
double *px = &y, *py = &x; // !! notice that these are swapped !!
x = *px; // A
y = *py; // B
Line A here overwrites the value of x. So even though py points to x, the original value of x is already lost, so y will be set to 43 because that's what's stored in x when the code reaches line B.
There are multiple ways to solve this:
create a copy of your three arrays, apply the permutation, and then copy back,
sort your points in-place by swapping values between the three arrays in your sort function, or
always use the pointers pl, pm, ph instead of the original arrays. So you won't need to copy things around at all.
The first is probably the simplest fix to the existing code:
double plarray[] = {0., 0.};
double pmarray[] = {2., 0.};
double pharray[] = {0., 2.};
// ... sort ...
pl = brop[0];
pm = brop[1];
ph = brop[2];
double tmp_plarray[2];
double tmp_pmarray[2];
double tmp_pharray[2];
// apply permutation into temporary arrays
update(tmp_plarray, pl);
update(tmp_pmarray, pm);
update(tmp_pharray, ph);
// copy back into original arrays
update(plarray, tmp_plarray);
update(pmarray, tmp_pmarray);
update(pharray, tmp_pharray);
Though I'd recommend going with the 3rd as it will simplify a lot of your code greatly while simultaneously being faster.

Related

Finding Third Coordinate Of a Triangle

i have an assignment for Programming class.
i have finished 80 percent of it, i am not able to complete the last part.
We have to find the distance between the shore and the boat(Point C) And Coordinates Of The Boat (Point C).
We are given (X,Y) coordinates And Angles of Points A and B.
Given A(76,316) B(57,516) Angle A = 17° and B = 17° Angle.
So Far i found AB= 200.9 AC= 105.04 BC = 105.04 C = 146° And the distance between the shore and the boat d = 30.71.
I tried everything but i am not able to find the Coordinates of Point C (Boat).
The Output is also Given : d = 30.71, Coordinates of C = C(97.07,418.90)
Please help me to find coordinates of Point C.
#include <stdio.h>
#include <math.h>
float radian(int degree);
float get_watchtowers_distance(int x1,int y1,int x2,int y2);
float get_boat_distance(float d,int alpha,int beta);
int main(){
get_watchtowers_distance(76,316,57,516);
get_boat_distance(200.90,17,17);
}
float radian(int degree){
return degree * (M_PI/180);
}
float get_watchtowers_distance(int x1,int y1,int x2,int y2){
return sqrtf(powf(x2-x1,2.0f)+powf(y2-y1,2.0f));
}
float get_boat_distance(float d,int alpha,int beta){
float a,b,c = 180 - (float)alpha - (float)beta;
a = (float)radian(alpha);
b = (float)radian(beta);
c = (float)radian(c);
printf("%.2f %.2f %.2f\n",a,b,c);
float B,A = d*sinf(a)/sinf(c);
B = d*sinf(b)/sinf(c);
float dist,area = 1.0f/2.0f*A*B*sinf(c);
dist = 2*area/d;
printf("AC Distance : %.2f , BC distance : %.2f\n",A,B);
printf("Boat Distance : %.2f\n", dist);
return dist;
}
Simpler approach to find d distance. We can express lengths of the left and right parts of base through d and cotangents
aa = d * ctg(alpha)
bb = d * ctg(beta)
aa + bb = l
d * (ctg(alpha) + ctg(beta)) = l
d = l / (ctg(alpha) + ctg(beta)) =
= l * sin(alpha) * sin(beta) / sin(alpha+beta)
Now you can find C coordinates using normalized vector ab and perpendicular component
abx = (b.x - a.x) / l
aby = (b.y - a.y) / l
aalen = d / tg(alpha)
c.x = a.x + abx * aalen - aby * d
c.y = a.y + aby * aalen + abx * d
There you go I have written some code for your question..
float get_coordinates(int x1, int y1, int x2, int y2, float alpha, float beta){
float a_angle_alpha, b_angle_beta, c_angle_delta;
c_angle_delta = 180 - (float)alpha - (float)beta;
printf("Alpha Angle in Degrees = %.2f\nBeta Angle in Degrees = %.2f\nDelta Angle in Degrees = %.2f\n", alpha, beta, c_angle_delta);
a_angle_alpha = (float)radian(alpha);
b_angle_beta = (float)radian(beta);
c_angle_delta = (float)radian(c_angle_delta);
printf("Alpha in radiance: %.2f\nBeta in radiance: %.2f\nDelta in radiance: %.2f\n", a_angle_alpha, b_angle_beta, c_angle_delta);
int u, v;
float d;
u = x2 - x1;
v = y2 -y1;
printf("u = %.d\nv = %.d\n", u, v);
float d1_distance_AB, d2_distance_BC, d3_distance_AC;
d1_distance_AB = sqrtf((u*u)+ (v*v));
d2_distance_BC = d1_distance_AB*sinf(b_angle_beta)/sinf(c_angle_delta);
d3_distance_AC = d1_distance_AB*sinf(a_angle_alpha)/sinf(c_angle_delta);
printf("Distance between A and B: %.2f\nDistance between B and C: %.2f\nDistance between A and C: %.2f\n",d1_distance_AB, d2_distance_BC, d3_distance_AC);
float RHS1, RHS2;
float x3, y3;
RHS1 = ((x1 * u) + (y1 * v) + (d2_distance_BC * d1_distance_AB * cosf(a_angle_alpha)));
RHS2 = ((y2 * u) - (x2 * v) - (d2_distance_BC * d1_distance_AB * sinf(a_angle_alpha)));
x3 = ((1 / (d1_distance_AB * d1_distance_AB)) * ((u * RHS1) - (v * RHS2)));
y3 = ((1 / (d1_distance_AB * d1_distance_AB)) * ((v * RHS1) + (u * RHS2)));
printf("Coordinates of Boat at point C is = %.2f:%.2f (x:y)", x3, y3);
float coordinates[2] = {x3,y3};
return coordinates;
}
Full Code:
#include <stdio.h>
#include <math.h>
float radian(int degree);
float get_watchtowers_distance(int x1,int y1,int x2,int y2);
float get_boat_distance(float d,int alpha,int beta);
float get_coordinates(int x1, int y1, int x2, int y2, float alpha, float beta);
int main(){
get_watchtowers_distance(76,316,57,516);
get_boat_distance(200.90,17,17);
get_coordinates(76,316,57,516,17,17);
}
float radian(int degree){
return degree * (M_PI/180);
}
float get_watchtowers_distance(int x1,int y1,int x2,int y2){
return sqrtf(powf(x2-x1,2.0f)+powf(y2-y1,2.0f));
}
float get_boat_distance(float d,int alpha,int beta){
float a,b,c = 180 - (float)alpha - (float)beta;
a = (float)radian(alpha);
b = (float)radian(beta);
c = (float)radian(c);
printf("%.2f %.2f %.2f\n", a, b, c);
float B,A = d*sinf(a)/sinf(c);
B = d*sinf(b)/sinf(c);
float dist,area = 1.0f/2.0f*A*B*sinf(c);
dist = 2*area/d;
printf("AC Distance : %.2f , BC distance : %.2f\n",A,B);
printf("Boat Distance : %.2f\n", dist);
return dist;
}
float get_coordinates(int x1, int y1, int x2, int y2, float alpha, float beta){
float a_angle_alpha, b_angle_beta, c_angle_delta;
c_angle_delta = 180 - (float)alpha - (float)beta;
printf("Alpha Angle in Degrees = %.2f\nBeta Angle in Degrees = %.2f\nDelta Angle in Degrees = %.2f\n", alpha, beta, c_angle_delta);
a_angle_alpha = (float)radian(alpha);
b_angle_beta = (float)radian(beta);
c_angle_delta = (float)radian(c_angle_delta);
printf("Alpha in radiance: %.2f\nBeta in radiance: %.2f\nDelta in radiance: %.2f\n", a_angle_alpha, b_angle_beta, c_angle_delta);
int u, v;
float d;
u = x2 - x1;
v = y2 -y1;
printf("u = %.d\nv = %.d\n", u, v);
float d1_distance_AB, d2_distance_BC, d3_distance_AC;
d1_distance_AB = sqrtf((u*u)+ (v*v));
d2_distance_BC = d1_distance_AB*sinf(b_angle_beta)/sinf(c_angle_delta);
d3_distance_AC = d1_distance_AB*sinf(a_angle_alpha)/sinf(c_angle_delta);
printf("Distance between A and B: %.2f\nDistance between B and C: %.2f\nDistance between A and C: %.2f\n",d1_distance_AB, d2_distance_BC, d3_distance_AC);
float RHS1, RHS2;
float x3, y3;
RHS1 = ((x1 * u) + (y1 * v) + (d2_distance_BC * d1_distance_AB * cosf(a_angle_alpha)));
RHS2 = ((y2 * u) - (x2 * v) - (d2_distance_BC * d1_distance_AB * sinf(a_angle_alpha)));
x3 = ((1 / (d1_distance_AB * d1_distance_AB)) * ((u * RHS1) - (v * RHS2)));
y3 = ((1 / (d1_distance_AB * d1_distance_AB)) * ((v * RHS1) + (u * RHS2)));
printf("Coordinates of Boat at point C is = %.2f:%.2f (x:y)", x3, y3);
float coordinates[2] = {x3,y3};
return coordinates;
}
Output:
0.30 0.30 2.55
AC Distance : 105.04 , BC distance : 105.04
Boat Distance : 30.71
Alpha Angle in Degrees = 17.00
Beta Angle in Degrees = 17.00
Delta Angle in Degrees = 146.00
u = -19
v = 200
Distance between A and B: 200.90
Distance between B and C: 105.04
Distance between A and C: 105.04
Coordinates of Boat at point C is = 97.07:418.90 (x:y)
To find the distance d directly without determining point C, first, you can calculate the area S of the triangle in two ways.
S = 0.5 * l * d
S = 0.5 * l * l * sin(a) * sin(b) / sin(a + b)
Equating the two and canceling out 0.5 * l gives d = l * sin(a) * sin(b) / sin(a + b).

Scanf in struct containing 'double' array doesnt work?

So I have to program a scalarproduct ((x1*y1)+(x2*y2)) with the use of structs and scanf.
However my program just skips y1 and counts both y1 and x2 as the same number even though I type in completely different numbers??
I did the following:
struct _point2d
{
double x[1]; // this means x1 is x[0] and x2 is x[1]
double y[1];
};
double PscalarProduct( double a, double b, double c, double d )
{
printf("The scalar product ((x1*y1) + (x2*y2)) (whereas x1 = %lf,
y1 = %lf, x2 = %lf, y2 = %lf) is %lf\n", a, b, c, d, (( a*b ) + ( c*d )) );
}
int main()
{
struct _point2d Vector;
Vector.x[1];
Vector.y[1];
printf("Enter x1 and y1 \n");
scanf("%lf", &(Vector.x[0]));
scanf("%lf", &(Vector.y[0]));
printf("Enter x2 and y2 \n");
scanf("%lf", &(Vector.x[1]));
scanf("%lf", &(Vector.y[1]));
PscalarProduct(Vector.x[0], Vector.y[0], Vector.x[1], Vector.y[1]);
return 0;
}
However if i run the program with the numbers 1[=x1] 2[=y1] 3[=x2] 4[=y2] I receive this text:
The scalar product ((x1*y1) + (x2*y2)) (whereas x1 = 1.000000, y1 = 3.000000, x2 = 3.000000, y2 = 4.000000) is 15.000000
How can this be that y1 and x2 are the same numbers??? y1 should be the number 2.00000.
The struct members x and y arrays can hold only one element each. But you are reading 2 elements as input.
In C, array index ranges from 0 to N-1. Your code has undefined behaviour due to out of bounds access.
Increase the array size:
struct _point2d
{
double x[2]
double y[2];
};

Quaternion to euler angles and euler angles to quaternion in C

I have been writing this code for checking the euler angles and quaternions, but it is not run correcly (or maybe I do not understand the rotations):
#include <stdio.h>
#include <math.h>
#define DR2D (180 / M_PI)
#define DD2R (M_PI / 180)
int main(int argc, char** argv)
{
float x, y, z;
x = 0 * DD2R;
y = 0 * DD2R;
z = 180 * DD2R;
printf("x=%f y=%f z=%f\n", x, y, z);
float sx = sin(x / 2);
float sy = sin(y / 2);
float sz = sin(z / 2);
float cx = cos(x / 2);
float cy = cos(y / 2);
float cz = cos(z / 2);
float qx, qy, qz, qw;
printf("sx = %f sy = %f sz = %f cx = %f cy = %f cz = %f\n", sx, sy, sz, cx, cy, cy);
qx = cx*cy*sz + sx*sy*cz;
qy = sx*cy*cz + cx*sy*sz;
qz = cx*sy*cz - sx*cy*sz;
qw = cx*cy*cz - sx*sy*sz;
printf("Quaternion -> (%f, %f, %f, %f)\n", qx, qy , qz , qw);
//------------------------------------------------------------------
float sqw = qw*qw;
float sqx = qx*qx;
float sqy = qy*qy;
float sqz = qz*qz;
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
float test = qx*qy + qz*qw;
if (test > 0.499*unit) { // singularity at north pole
x = 2 * atan2(qx,qw);
y = M_PI/2;
z = 0;
}
else if (test < -0.499*unit) { // singularity at south pole
x = -2 * atan2(qx,qw);
y = -M_PI/2;
z = 0;
}
else {
x = atan2(2*qy*qw-2*qx*qz , sqx - sqy - sqz + sqw);
y = asin(2*test/unit);
z = atan2(2*qx*qw-2*qy*qz , -sqx + sqy - sqz + sqw);
}
printf("recover euler x=%.2f y=%.2f z=%.2f\n",
x * DR2D, y * DR2D, z * DR2D);
}
Because the output is very weird:
For example: x 180º y 90º z 90º
x=3.141593 y=1.570796 z=1.570796
sx = 1.000000 sy = 0.707107 sz = 0.707107 cx = -0.000000 cy = 0.707107 cz = 0.707107
Quaternion -> (0.500000, 0.500000, -0.500000, -0.500000)
reconversion euler x=270.00 y=90.00 z=0.00
Or for example x 90º y 90º z 90º
x=1.570796 y=1.570796 z=1.570796
sx = 0.707107 sy = 0.707107 sz = 0.707107 cx = 0.707107 cy = 0.707107 cz = 0.707107
Quaternion -> (0.707107, 0.707107, 0.000000, 0.000000)
recover euler x=180.00 y=90.00 z=0.00
The algorithm you use has a domain that lies in the interval [0,pi/2) only, the first quadrant. Or, because you want the input to be in degrees, between 0 (zero) inclusive and 90 degrees exclusive.

Implementing the scott T method

I've trying to implement a math formal to convert a 3 phase system into 2 phases, using the following code:
#include <stdio.h>
#include <math.h>
#define PI 3.14159265358979
void getAngle( float xValue , float yValue, float zValue){
float x = 0.0;
float y = 0.0;
float z = 0.0;
double rad_angle =0.0;
double angle =0 ;
double zaehler = 0.0;
double nenner = 0.0;
z=xValue;
y=yValue;
x=zValue;
printf(" Getangle \n" );
printf(" X = %lf , [BY = %lf , Z = %lf \n " , x,y,z);
zaehler =z-x;
nenner = ((y-x) -((x-z)/2-(z-y)/2))*(2*sqrt(3));
printf (" the sin value is : %lf \n" , zaehler);
printf (" the cos value is : %lf \n",nenner);
rad_angle = atan2(nenner,zaehler);
printf("Radangle = %lf \n",rad_angle);
angle =( rad_angle * 180/PI);
printf("Angle in degree = %lf \n",angle);
}
void setAngle(float angle ){
float x = 0 ;
float y = 0 ;
float z = 0 ;
printf(" the given angle is : %lf \n",angle);
angle = angle *PI/180;
x = sin(angle);
y = sin(angle+(120* (PI/180.0)));
z = sin(angle+(240* (PI/180.0)));
printf(" Set angle \n" );
printf(" the x value : %f ,\n the y value : %f ,\n the z value :%f ",x,y,z);
getAngle(x,y,z);
}
int main (){
float angle = 0;
while (1){
printf(" angle in Degrees \n");
scanf("%f" ,&angle);
printf(" sinus angle : %f", sin(angle*PI/180));
setAngle(angle);
}
return 0;
}
and here is what I'm trying to implement:
I never get the angle that I give back.
Any idea what I'm doing wrong here ?
nenner = (y -((x+z)/2))*(2/sqrt(3));
here it is fixed up, I had to chage the order of x,y,z and fix the nenner formula.
void getAngle( float xValue , float yValue, float zValue){
float x = 0.0;
float y = 0.0;
float z = 0.0;
float rad_angle =0.0;
float angle =0 ;
float zaehler = 0.0;
float nenner = 0.0;
y=xValue;
z=yValue;
x=zValue;
printf(" Getangle \n" );
printf(" X = %lf , [BY = %lf , Z = %lf \n " , x,y,z);
zaehler =z-x;
nenner = (y -((x+z)/2))*(2/sqrt(3));
printf (" the sin value is : %lf \n" , zaehler);
printf (" the cos value is : %lf \n",nenner);
rad_angle = atan2(nenner,zaehler);
printf("Radangle = %lf \n",rad_angle);
angle =( rad_angle * 180/PI);
printf("Angle in degree = %lf \n",angle);
}

Getting the formatting right with sprintf()

I'm trying to get some formatting done in my sprintf statement, but it doesn't seem to work as I expect. Here is the line:
n = sprintf(buffer, "x = %d.%d, y = %d.%d, z = %d.%d \n", x1, x2, y1, y2, z1, z2);
In that printout x1 is the whole part of the number, and x2 is the fractional part. All would be well, except I need to pad x2, y2, and z2 to always be 2 digits - meaning I need to pad with leading zeros.
With examples that I see online it seems like doing this should work:
n = sprintf(buffer, "x = %d.%02d, y = %d.%02d, z = %d.%02d \n", x1, x2, y1, y2, z1, z2);
However, that instead produces something like this:
x = 2.2d, y = 37.2d, z = 2.2d
The 37 above is actually x2, and it apparently got shifted over in place of y1. I tried putting brackets around the '02', but that doesn't do anything either.
I have tried splitting up the period too like this: (but that didn't work)
n = sprintf(buffer, "x = %d. %02d, y = %d. %02d, z = %d. %02d \n", x1, x2, y1, y2, z1, z2);
I'm not really sure what's wrong... I'd appreciate any help. This isn't particularly vital to do in sprintf (I could theoretically write some 'if' statements and get it working that way), but it'd be nice.
Thanks!
This is a sample code and output.
float x1 = 10.12222;
float y1 = 20.23333;
float z1 = 30.34444;
int xi = 10;
int yi = 20;
int zi = 30;
int x0 = 5;
int y0 = 5;
int z0 = 5;
int xl = 10;
int yl = 10;
int zl = 10;
char chr[512];
printf("x = %5.2f, y = %5.2f, z = %5.2f\n", x1, y1, z1);
printf("x = %10d, y = %10d, z = %10d\n", xi, yi, zi);
printf("x = %010d, y = %010d, z = %010d\n", xi, yi, zi);
printf("x = %-10d, y = %-10d, z = %-10d\n", xi, yi, zi);
printf("x = %10.5d, y = %10.5d, z = %10.5d\n", xi, yi, zi); // DYNAMIC
/* Dynamic formatting of DYNAMIC commented line*/
sprintf(chr, "Dynamic: x = %%%d.%dd, y = %%%d.%dd, z = %%%d.%dd\n",
xl, x0, yl, y0, zl, z0);
printf(chr, xi, yi, zi);
The output will be like this.
x = 10.12, y = 20.23, z = 30.34
x = 10, y = 20, z = 30
x = 0000000010, y = 0000000020, z = 0000000030
x = 10 , y = 20 , z = 30
x = 00010, y = 00020, z = 00030
Dynamic: x = 00010, y = 00020, z = 00030
%x.yd means,
x - Total characters for the integer.
y - Padding with 0s within that length.
%10.5d will give following results for 10, 100, 1000, 10000, 100000, 100000
bbbbbbbbbb => Spaces
00010
00100
01000
10000
100000
1000000
I hope this helps for your formatting.

Resources