2016-09-19 2 views
1

В настоящее время я пытаюсь простую линию вращения в sdl, и я нашел функцию, которая вращает точку вокруг другой точки. Здесь он (изменен для работы с sdl).C++ Вращающаяся линия становится короче

SDL_Point rotate_point(double cx, double cy, double angle, SDL_Point p) 
{ 
    double pi = acos(-1); 
    double rotation_angle = (double)angle/180.0 * pi; 
    double s = sin(rotation_angle); 
    double c = cos(rotation_angle); 

    // translate point back to origin: 
    p.x -= cx; 
    p.y -= cy; 

    // rotate point 
    double xnew = p.x * c - p.y * s; 
    double ynew = p.x * s + p.y * c; 

    // translate point back: 
    p.x = xnew + cx; 
    p.y = ynew + cy; 

    return p; 
} 

Теперь у меня возникает проблема, когда линия становится короче и короче, пока она не остановится в центральной точке, вращая ее вокруг. Я не знаю, почему.

Вот как им с помощью функции:

double angle1=0.1, angle2=0,oldangle1=0,oldangle2=0; 
    SDL_Point line11 = { 10,0 }, line12 = { 110,0 }, line21 = { 110,0 }, line22 = { 210,0 }; 
    SDL_Event event; 
    int mousex = 0, mousey = 0; 
    while (SDL_PollEvent(NULL)) { 
     SDL_GetMouseState(&mousex, &mousey); 
     if (GetAsyncKeyState('W')) 
      angle1 += 0.1; 
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); 
     SDL_RenderClear(renderer); 
     if (angle1 < oldangle1-0.1||angle1 > oldangle1 + 0.1) { 
      line12 = rotate_point(0, 0, (angle1-oldangle1), line12); 
      line21 = rotate_point(0, 0, (angle1 - oldangle1), line21); 
      oldangle1 = angle1; 
     } 
     if (angle2 < oldangle2 - 0.1 || angle2 > oldangle2 + 0.1) { 
      line22 = rotate_point(line21.x,line21.y, (angle2 - oldangle2), line22); 
      oldangle2 = angle2; 
     } 
     if (angle2 == 0) 
      angle2 = angle1; 
     printf("%f ", angle2); 
     SDL_SetRenderDrawColor(renderer, 0, 255, 0, 0); 
     SDL_RenderDrawLine(renderer, line11.x, line11.y, line12.x, line12.y); 
     SDL_RenderDrawLine(renderer, line21.x, line21.y, line22.x, line22.y); 
     //solveIK(&angle1, &angle2, false, 100, 100, mousex, mousey); 
     //angle1 = get_degrees(angle1); 
     //angle2 = get_degrees(angle2); 
     SDL_RenderPresent(renderer); 
     SDL_Delay(16); 

    } 

Я знаю, что это невероятно грязный, но ив только начали с SDL и C++. я попытаюсь исправить это после того, как я получил его на работу.

Что ив уже пробовал:

Различные функции для вращения. Все они кажутся хуже с точки зрения сокращения линии. Скорее всего, это не проблема с функцией вращения.

Переписывание кода. Это версия 3, и она работает лучше всего, но также является наихудшим видом.

+1

просто не связанный совет: очистка после его работы - это то, что я всегда говорю себе, но я никогда этого не делаю. На самом деле гораздо проще заставить его работать, если вы сохраняете его с самого начала. – user463035818

+0

Что такое cx и cy? Центрирующие центры вращения? – SingerOfTheFall

+0

Jeah. cx = Centerx для выстрела.) – MoustacheSpy

ответ

3

Не перебирайте.

Начать с начальных пунктов. Теперь примените поворот.

Если у вас есть новое вращение, начните с начальных точек и примените новый поворот. Не вращать результат первого вращения.

В целом операции с плавающей запятой индуцируют ошибку вдали от теоретического результата. Округление целых чисел еще больше ошибок (не уверен, что ваш код делает это). Каскадирование большого числа операций с плавающей запятой приведет иногда к мусору.

Теперь добавление углов также будет иметь ошибку округления, но не примечательным образом: он будет вращаться больше/меньше, чем он должен иметь, а не растягивать/сжимать линию. Опять же здесь вы можете заменить повторное добавление с фиксированным количеством умножений, чтобы уменьшить это, если вам все равно.

+0

Можете ли вы объяснить подробно? Вы имеете в виду, что вместо (angle1-oldangle) я должен установить point1 в его базовые значения и просто применить angle1? – MoustacheSpy

+0

спасибо моему мужчине. Я изменил его, как вы сказали, и проблема (в основном) исчезла. Его все еще немного неточно, но я могу жить с этим. – MoustacheSpy