Неправильные преобразования полярных координат в декартовы. Что означает -0?

Я получаю неправильные преобразования из полярных координат в декартовы и наоборот. Мой код производит странные точки вроде (1, -0). Я использую этот калькулятор для проверки своих конверсий. Также одно из преобразований полностью неверно, когда я конвертирую обратно в декартовы координаты.

Точка b: (0,1) => (1,1.5708) => (0,0)

#include <math.h>
#include <iostream>
/* Title:      Polar - Cartesian Coordinate Conversion
*  References: HackerRank > All Domains > Mathematics > Geometry > Polar Angles
*              Cartesian to Polar: (radius = sqrt(x^2 + y^2), theta = atan(y/x))
*              Polar to Cartesian: (x = radius*cos(theta), y = radius*sin(theta))
*/

//General 2D coordinate pair
struct point{
    point(float a_val, float b_val) : a(a_val), b(b_val){;};
    point(void){;};
    float a, b;
};
//Converts 2D Cartesian coordinates to 2D Polar coordinates 
point to_polar(/*const*/ point& p){//*** Conversion of origin result in (r, -nan) ***
    point ans(sqrt(pow(p.a,2) + pow(p.b,2)), atan(p.b/p.a));
    return ans;
}
//Converts 2D Polar coordinates to 2D Cartesian coordinates
point to_cartesian(/*const*/ point& p){
    point ans(p.a * cos(p.b), p.a * sin(p.b));
    return ans;
}
//Outputs 2D coordinate pair
std::ostream& operator<<(std::ostream& stream, const point& p){
    stream << "(" << p.a << "," << p.b << ")";
    return stream;
}
int main(){
    //Test Points - Cartesian
    point a(0, 0);
    point b(0, 1);
    point c(1, 0);
    point d(0,-1);
    point e(-1,0); 

    //Print Cartesian/Rectangular points
    std::cout << "Cartesian Coordinates:" << std::endl;
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    std::cout << d << std::endl;
    std::cout << e << std::endl; 

    //Print Cartesian to Polar
    std::cout << "Polar Coordinates:" << std::endl;
    std::cout << to_polar(a) << std::endl;//Failure (0,-nan)         
    std::cout << to_polar(b) << std::endl;//Success
    std::cout << to_polar(c) << std::endl;//Success
    std::cout << to_polar(d) << std::endl;//Success
    std::cout << to_polar(e) << std::endl;//Failure (1,-0)  

    //Print Polar to Cartesian
    std::cout << "Cartesian Coordinates:" << std::endl;
    std::cout << to_cartesian(a) << std::endl;//Success
    std::cout << to_cartesian(b) << std::endl;//Failure (0,0)
    std::cout << to_cartesian(c) << std::endl;//Success
    std::cout << to_cartesian(d) << std::endl;//Failure (0,-0)
    std::cout << to_cartesian(e) << std::endl;//Failure (-1,-0)


    return 0;
}

person dylan    schedule 22.06.2015    source источник
comment
Вы несколько раз делите на ноль.   -  person molbdnilo    schedule 22.06.2015
comment
@molbdnilo: Переход на atan2, как я предлагаю, также решит эту проблему.   -  person Ben Voigt    schedule 22.06.2015
comment
Очень хорошее обсуждение того, когда использовать atan2, можно найти здесь: stackoverflow.com/a/12011762/1923699   -  person Tyler Jandreau    schedule 22.06.2015


Ответы (2)


Вы переводите в декартову систему точек, которые уже находятся в декартовой системе координат. Вы хотите:

std::cout << "Cartesian Coordinates:" << std::endl;
std::cout << to_cartesian(to_polar(a)) << std::endl;
std::cout << to_cartesian(to_polar(b)) << std::endl;
//...

Изменить: использование atan2 решает проблему NaN, (0, 0) преобразуется в (0, 0), что нормально.

person Anton Savin    schedule 22.06.2015
comment
Итак, вы говорите, чтобы преобразовать в полярный, я делаю это? std::cout << to_cartesian(to_polar(a)) << std::endl; - person dylan; 22.06.2015
comment
@dylan, чтобы преобразовать в полярный, вы используете to_polar, чтобы преобразовать обратно в декартово, вы должны либо сохранить результат to_polar, который равен a1 = to_polar(a); a2 = to_cartesian(a1);, либо использовать to_cartesian(to_polar(a)). - person Anton Savin; 22.06.2015
comment
Когда я это делаю, координаты вроде правильные. Он выводит ноль как очень маленькое число. Пример: (-4.37114e-08,1). Есть ли способ исправить это. - person dylan; 22.06.2015
comment
@dylan для повышения точности используйте double. Но все равно ноль не получишь. Для хорошего результата попробуйте std::cout.setf(std::ios::fixed);. - person Anton Savin; 22.06.2015

В качестве первого шага вам нужно переключиться на atan2 вместо atan при преобразовании в полярные координаты. atan дает неверные результаты для половины плоскости.

person Ben Voigt    schedule 22.06.2015