Russian Qt Forum
Октябрь 01, 2024, 14:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: построение стрелочки вектора  (Прочитано 6493 раз)
borik120
Гость
« : Ноябрь 12, 2010, 22:18 »

вообщем рисую векторную диаграмму, несколько последовательных векторов на координатной плоскости. (декартова система)
столкнулся с такой проблемой: при отрисовке вектора не могу нарисовать стрелочку вектора.
известны координаты начала(x1:y1) и конца (x2:y2) вектора. нужно найти координаты конца стрелки вектора (x3:y3);
я пытался их искать через углы альфа и бета (см. вложение) находил бета из скалаярного произведения вектора, на направляющий вектор оси х. и потом находил x3:y3 исхоря из угла (бета - альфа + 90). в подробности вдаваться не буду, думаю не стоит. вообщем этот способ работает только для векторов в первой четверти координат.
думаю, может кто то уже сталкивался с подобной задачей, и есть более простое решение?
естественно вектор может быть направлен в любую сторону.

« Последнее редактирование: Ноябрь 12, 2010, 22:57 от borik120 » Записан
ufna
Гость
« Ответ #1 : Ноябрь 13, 2010, 07:37 »

Рисуешь линию, идешь в точку конца, делаешь QPainter'у поворот на посчитанное на основе вектора число градусов, чтобы стрелочку можно было рисовать в системе координат уже "с поворотом", просто как к примеру две линии (0, 0, -10, -10) и (0, 0, -10, 10).
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Ноябрь 13, 2010, 09:33 »

2 ufna
Чего-то я сомневаюсь, что borik120 тебя поймёт )
« Последнее редактирование: Ноябрь 13, 2010, 09:36 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
ufna
Гость
« Ответ #3 : Ноябрь 13, 2010, 10:55 »

Надо юзать QPainter::translate() и QPainter::rotate(), ну а далее если сам не разберется, то велкам, хотя вроде зная "скалярное произведение", то все должно быть очевидно Улыбающийся
Записан
borik120
Гость
« Ответ #4 : Ноябрь 13, 2010, 18:21 »

вот получился такой код:
вначале две функции возвращающие скалярное произведение, и длину вектора соответственно.
Код:
double AlgMultiplieVect(double x1,double y1,double x2, double y2)
  {
  double rez;
  rez = x1*x2+y1*y2;
  return rez;
  }


  double VectLength(double x, double y)
  {
  double rez;
  rez = sqrt(x*x + y*y);
  return rez;
  }


   void drawVect(Complex a, double mb_e, double mb_cx, double mb_cy,QString text)
   {

       double k;
       k = 50/mb_e;
       double x1,x2,y1,y2;
       double betacos,beta;
       double strx1,stry1;
      
       strx1  = 10; // направляющий вектор оси оХ
       stry1 = 0;
      
       x1 = mb_cx; // точка начала вектора
       y1 = mb_cy;

       x2 = mb_cx + a.re*k;  //точка конца вектора
       y2 = mb_cy - a.im*k;

       //cos угла между  вектором и направлением оси ох
       betacos = (AlgMultiplieVect(x2,y2,strx1,stry1))/(VectLength(x2,y2)*VectLength(strx1,stry1));
       // сам угол
       beta  = acos(betacos);

       //рисуем основание вектора
       paint.drawLine(x1,y1,x2,y2);
       //подписываем вектор
       paint.drawText((x1+x2)/2 + 15,(y1+y2)/2,text);

       // сохраняю текущее положение координатной оси
       paint.save();
       paint.translate(x2,y2);
       paint.rotate(-(beta*57.295));  //умножаю на 57.295 чтобы получить градусы
       paint.drawLine(-10,-5,0,0);
       paint.drawLine(-10,5,0,0);

       //возвращаю координатную ость в нормальное положение
       paint.restore();




   }

переменная k  - это коэффицент, как относятстя единичный отрезок в пикселях на рисунке с значением единичного отрезка. (вычисляется ранее). вычисление x2,y2 тоже точно правильное.
так вот теперь проблема в том, что стрелочка получается немного недокрученная\ перекрученная. (см рисунок). здесь еще более-менее, бывает вообще сильно неровная.
« Последнее редактирование: Ноябрь 13, 2010, 18:29 от borik120 » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Ноябрь 13, 2010, 18:37 »

Копайте расчёт угла.
И я бы увеличил точность расчёта градусов - не стоит использовать 57.295 - всё-таки, например, (180 / 3.14159265) будет точнее - пусть машина считает)
Записан

Qt 5.11/4.8.7 (X11/Win)
borik120
Гость
« Ответ #6 : Ноябрь 13, 2010, 18:43 »

увеличивал число до (beta*57.29577951308)и в виде (beta*180 / 3.14159265) но результат то же. может расчет угла из формулы скалярного произведения может давать неточный результат?
« Последнее редактирование: Ноябрь 13, 2010, 18:45 от borik120 » Записан
ufna
Гость
« Ответ #7 : Ноябрь 13, 2010, 18:44 »

Как уже было сказано выше, проблема видится именно в рассчете угла - на рисунке видно что он однозначно посчитан где-то на четверть-треть меньшим чем должен быть. И не стоит использовать такие "градусные" константы.
Записан
ufna
Гость
« Ответ #8 : Ноябрь 13, 2010, 18:46 »

блин, медленно пишу ))


ты проверь просто - задай отрезок, когда точно знаешь угол. И потом посмотри какой угол у тебя насчитает программа, выведи его. Сравни и можно начать искать ошибку.
Записан
borik120
Гость
« Ответ #9 : Ноябрь 13, 2010, 18:56 »

только что посчитал, он все правильно вывел. получилось 45гр.
Код:
testx1 = 4; testy1 = 4;
       testcos = (AlgMultiplieVect(testx1,testy1,strx1,stry1))/(VectLength(testx1,testy1)*VectLength(strx1,stry1));
       testangle = acos(testcos)*180 / 3.14159265 ;
       qDebug() << testangle;

во вложении другой вектор. тут по моему дело не в угле)
« Последнее редактирование: Ноябрь 13, 2010, 18:57 от borik120 » Записан
ufna
Гость
« Ответ #10 : Ноябрь 13, 2010, 19:01 »

где 45 градусов? Покажи вывод.

у тебя мастаб относительный осей какой?

выложи минимальный код.
Записан
borik120
Гость
« Ответ #11 : Ноябрь 13, 2010, 19:23 »

вообще я рисую на графике комплексные числа с помощью векторов.

Код:
 double step2 (Complex a)
  {
  double rez;
  rez = sqrt(a.im*a.im+a.re*a.re);
        return rez;
  }

  double AlgMultiplieVect(double x1,double y1,double x2, double y2)
  {
  double rez;
  rez = x1*x2+y1*y2;
  return rez;
  }
  double VectLength(double x, double y)
  {
  double rez;
  rez = sqrt(x*x + y*y);
  return rez;
  }

   void drawVect(Complex a, double mb_e, double mb_cx, double mb_cy,QString text)
   {

       double k;
       k = 50/mb_e;
       double x1,x2,y1,y2;
       double betacos,beta;
       double strx1,stry1,testx1,testy1,testcos,testangle;

       strx1  = 1; // направляющий вектор оси оХ
       stry1 = 0;

       testx1 = 4; testy1 = 4;

       x1 = mb_cx; // точка начала вектора
       y1 = mb_cy;

       x2 = mb_cx + a.re*k;  //точка конца вектора
       y2 = mb_cy - a.im*k;

       //cos угла между  вектором и направлением оси ох
       betacos = (AlgMultiplieVect(x2,y2,strx1,stry1))/(VectLength(x2,y2)*VectLength(strx1,stry1));
       // сам угол
       beta  = acos(betacos);

       //рисуем основание вектора
       paint.drawLine(x1,y1,x2,y2);
       //подписываем вектор
       paint.drawText((x1+x2)/2 + 15,(y1+y2)/2,text);

       // сохраняю текущее положение координатной оси
       paint.save();
       paint.translate(x2,y2);
       paint.rotate(-(beta*180 / 3.14159265));  //умножаю на 57.295 чтобы получить градусы
       paint.drawLine(-10,-7,0,0);
       paint.drawLine(-10,7,0,0);

       //возвращаю координатную ось в нормальное положение
       paint.restore();

       testx1 = 4; testy1 = 4;
       testcos = (AlgMultiplieVect(testx1,testy1,strx1,stry1))/(VectLength(testx1,testy1)*VectLength(strx1,stry1));
       testangle = acos(testcos)*180 / 3.14159265 ;
       qDebug() << testangle;




   }
//---------------------------------------------------------------------------
 //построение графика;
 void drawCoordinateSystem(Complex mb_a1,Complex mb_a2,Complex mb_a3,QString s_a1,QString s_a2,QString s_a3)
 {
     int c_x = 525;
     int c_y = 525;
     double max;
     double e;

     QString a[11];

paint.drawLine(25,525,1025,525);    paint.drawLine(1015,520,1025,525); paint.drawLine(1015,530,1025,525); //ось X
paint.drawLine(525,25,525,1025);    paint.drawLine(520,35,525,25);     paint.drawLine(530,35,525,25); //ось Y
paint.drawText(1025,550,"+"); paint.drawText(25,550,"-");
paint.drawText(535,25,"+j"); paint.drawText(535,1025,"-j");

max = MaxOfI(step2(mb_a1),step2(mb_a2),step2(mb_a3));    //нахожу самый длинный из векторов

e = max/8;                                                                    //относительно самого длинного вектора нахожу ед. отрезок
for (int i =1; i<=10;i++)
{
   a[i] =  a[i].setNum(e*i,'g',2);
paint.drawLine(c_x+i*50,c_y+5,c_x+i*50,c_y-5);               // тут я наношу значения на координатные оси
paint.drawText(c_x+i*50,c_y+20,a[i]);
}


drawVect(mb_a2,e,c_x,c_y,"I6");
drawVect(mb_a3,e,c_x,c_y,"I3");
drawVect(mb_a1,e, c_x + (mb_a3.re*50)/e,   c_y - (mb_a3.im*50)/e,   "I4");







 }


Записан
borik120
Гость
« Ответ #12 : Ноябрь 13, 2010, 21:28 »

все нашел ошибку. проблема была в моей невнимательности.
в функцию, где высчитывалась длина вектора, передавал не первоначальные координаты вектора, а координаты вектора сложенные с центром на рисунке. а из за того что оси Y на рисунке и в программе отличаются направлением, получался недочет.
Спасибо всем за проявленный интерес! Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.