rotating points getting wrong output

I'm given various names of stars on 2d plane and X, Y coordinates along with N deg of Counter clockwise rotation. I have to output them in smallest y, then x order, after the rotation is done. I can't figure out why my code is wrong as I feel like my logic is correct... any help?

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
#include <string>    
#include <algorithm>
#include <iostream> 
#include <iomanip>
#include <math.h>
using namespace std;

double get_degrees(double input)
{
    const double halfC = M_PI / 180;
    return input * halfC;
}
class Star{
    string n;
    double x, y;
    public:
    Star(){}
    Star(double a, double b, string s){x=a; y=b; n=s;}
    double getx(){return x;}
    double gety(){return y;}
    string getn(){return n;}
    
    void setx(double a){x=a;}
    void sety(double b){y=b;}
    void setn(string n1){n=n1;}
};

bool operator<(Star &a, Star &b)
{
    if(a.gety()!=b.gety()){
        return a.gety()<b.gety();
    }
    else{
        return a.getx()>b.getx();
    }
}

int main()
{int input; double rot;
cin>>input>>rot;
cin.ignore();
Star s[input];
for (int i=0; i<input; i++){
    string name; double x, y;
    cin>>name>>x>>y;
    Star temp(x,y,name);
    s[i] = temp;
   // convert to polar, add the rot, then... MAGIC!
    //r = √ ( x2 + y2 )
    //θ = tan-1 ( y / x ) -- this is in radians
    
    /* alt way?
    double r = (double)(sqrt(x*x+y*y));
    double angle = (double)(atan(y/x))+(double)(rot);
     x = r × cos( θ ), y = r × sin( θ )*/
    
    // x= round ( y*cos(360-rot)-x*sin)
    // y = round (-y*sin(360-rot)+x*cos)
    double angle = 360-rot; //avoid weird math issues
    angle = get_degrees(angle);
    //cout<<"r = "<<r<<" angle = "<< angle<< " ";
    s[i].setx(y*cos(angle)-x*sin(angle));
    s[i].sety(-y*sin(angle)+x*cos(angle));
  }
  sort(s, s+input);
  for (Star s1: s){
      cout<<s1.getn()<<" ";
  }
  return 0;
}


sample input: 33 194
Albireo -85 93
Nembus -655 -360
Deneb -299 28
Alcor -873 414
Castor -811 -524
Kastra -865 -610
Heka -201 -981
Bellatrix -110 -814
Yildun 997 220
Electra -321 -650
Thabit -470 344
Mizar 528 -940
Rigel -856 182
Lesath 421 -309
Gemma 52 144
Diadem 769 968
Algol -763 -886
Unuk -393 -62
Procyon 142 -265
Alcyone -649 332
Betelgeuse 211 -513
Zosma 722 -990
Fomalhaut -494 -388
Polaris -804 -498
Sirius 832 -124
Vega -147 -639
Mira -781 -620
Pherkad -578 -637
Kochab 563 844
Media 55 -386
Jabbah -13 -176
Capella -418 224
Altair -62 189

output: Yildun Diadem Sirius Kochab Zosma Lesath Mizar Gemma Betelgeuse Procyon Altair Media Jabbah Albireo Deneb Vega Bellatrix Capella Thabit Unuk Heka Electra Alcyone Fomalhaut Pherkad Nembus Alcor Rigel Polaris Mira Castor Algol Kastra

expected: Diadem Kochab Yildun Thabit Alcor Altair Alcyone Gemma Capella Sirius Albireo Rigel Deneb Unuk Jabbah Lesath Procyon Media Betelgeuse Fomalhaut Nembus Vega Polaris Castor Electra Pherkad Mizar Zosma Mira Kastra Bellatrix Heka Algol
Didn't run the program, but just a guess,
1
2
3
4
5
6
7
8
9
bool operator<(Star &a, Star &b)
{
    if(a.gety()!=b.gety()){
        return a.gety()<b.gety();
    }
    else{
        return a.getx()>b.getx();
    }
}

should it be a.getx() < b.getx() ?

360-rot; //avoid weird math issues
What do you mean by this?
Look at Wikipedia's rotation matrix.
https://en.wikipedia.org/wiki/Rotation#Axis_of_2_dimensional_rotations
See how it's
[ +cos   -sin  
  +sin   +cos ]

But your program is doing
[ +cos   -sin  
  -sin   +cos ]


1
2
3
    double angle = get_radians(rot);
    s[i].setx(x*cos(angle) - y*sin(angle));
    s[i].sety(x*sin(angle) + y*cos(angle));


PS: Your "get_degrees" function should be called "get_radians"... or "deg_to_rad" or something like that.
Last edited on
I fixed the getx comparison and used your idea but the output is now completely wrong lol
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
#include <iostream> 
#include <iomanip>
#include <string>    
#include <algorithm>
#include <cmath>
using namespace std;

double to_radians(double deg) { return deg * M_PI / 180; }
double to_degrees(double rad) { return rad * 180 / M_PI; }

struct Star {
    string name;
    double x, y;

    bool operator<(Star& that) {
        return y != that.y ? y < that.y : x < that.x;
    }
};

int main() {
    int nstars;
    double rot;

    cin >> nstars >> rot;
    cin.ignore(999, '\n');

    rot = to_radians(rot);

    auto stars = new Star[nstars];

    for (int i = 0; i < nstars; i++) {

        string name;
        double x, y;
        cin >> name >> x >> y;
        cin.ignore(999, '\n');

        stars[i].name = name;
        stars[i].x = x * cos(rot) - y * sin(rot);
        stars[i].y = x * sin(rot) + y * cos(rot);
    }

    sort(stars, stars + nstars);

    for (int i = 0; i < nstars; i++) cout << stars[i].name << ' ';
    cout << '\n';

    delete[] stars;
}

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
#include <iostream> 
#include <string>    
#include <algorithm>
#include <cmath>
#include <complex>
using namespace std;

using CMPLX = complex<double>;

struct Star
{
   string name;
   CMPLX pos;
};

bool sortBy( Star a, Star b ) { CMPLX d = a.pos - b.pos; return ( imag( d ) ? imag( d ) : real( d ) ) < 0; }

int main()
{
   int nstars;
   double rot;

   cin >> nstars >> rot;
   CMPLX rotFactor = polar( 1.0, rot * M_PI / 180.0 );

   Star * stars = new Star[nstars];
   for (int i = 0; i < nstars; i++)
   {
      double x, y;
      cin >> ws >> stars[i].name >> x >> y;
      stars[i].pos = CMPLX( x, y ) * rotFactor;
   }

   sort( stars, stars + nstars, sortBy );
   for ( int i = 0; i < nstars; i++ ) cout << stars[i].name << ' ';
   cout << '\n';

   delete[] stars;
}
Last edited on
ah, thanks. I thought I had to calculate deg then add rot to it. Didn't realize that you could just use the rot to figure out x and y
Topic archived. No new replies allowed.