Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.03.2018, 05:01   #1
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию Геометрия, углы треугольника

Здравствуйте.
Недавно я столкнулся с преинтереснейшей задачей - наведение объекта (картинки) на цель.
Нужно вращать картинку, а вращать её нужно на определённый угол.
У меня имеются координаты центра картинки, и координаты цели.
По сути, мне нужно повернуть изображение на тот же угол, что и угол между прилежащим катетом и гипотенузой прямоугольного треугольника (там уже зависит от четверти координат). Пошёл я считать углы треугольника, стороны которого можно получить из имеющихся координат ...
Когда у меня началась геометрия (7 класс) - я в школе начал пинать сами знаете что, поэтому первым делом я нагуглил формулы углов, и столкнулся с тем, что у меня формулы не углов, а их косинусов. Информация о том, что из косинусов можно получить углы с помощью арккосинуса - у меня почему то не работает.
В итоге, я соорудил вот такую вот конструкцию:
Код:
double
	a=Math.Abs(coords.X-centerPos.X),
	b=Math.Abs(coords.Y-centerPos.Y),
	angleA=90,angleB,angleC;
	/*c=Math.Sqrt(Math.Pow(a,2)+Math.Pow(b,2)),
	angleA=Math.Acos(Math.Cos(((a*(c*c))-(a*(b*b))+(b*(c*c))/(2*a*c*b*c)))),
	angleB=Math.Acos(Math.Cos(((a*(b*b))-(a*(c*c))+(b*(c*c))/(2*a*b*b*c)))),
	angleC=Math.Acos(Math.Cos(((a*(b*b))-(b*(c*c))+(a*(c*c))/(2*a*b*a*c))));*/
if (a>b)
{
	angleC=45*(1/a*b);
	angleB=90-angleC;
} else
if (b>a)
{
	angleB=45*(1/b*a);
	angleC=90-angleB;
} else
	angleB=angleC=45;
И в принципе, это работает правильно. Какой угол мне нужен (angleB или angleC) - нужно ещё разбираться по четвертям.
Комментированный блок кода - это формулы, честно спёртые отсюда.
Формулы в других местах мой мозг не воспринимает правильно (для вычисления угла a необходим угол a).

Я понимаю, что мой код - это откровенная халтура, и получение углов в каком то смысле "пальцем в небо". Поэтому вопрос: как всё таки правильно считать углы ?
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 09.03.2018 в 06:26.
OmegaBerkut вне форума Ответить с цитированием
Старый 09.03.2018, 08:02   #2
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,792
По умолчанию

косинусы и арккосинысу и прочие функции тут а языках программирования в радианах считаются. так что, ты умножай на ПИ и дели на 180. и будет тебе счастье в привычных градусах.
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
NetSpace вне форума Ответить с цитированием
Старый 09.03.2018, 09:56   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Обычно для этих целий используют актангенс. Причём есть арктангенс от двух параметров - он автоматически учитывает знаки и рассчитывает четверти. Более того это 1 команда процессора.
atan2(dy,dx)
arctan2(dx, dy)

В разных языках разные обозначения. И порядок параметров отличается.
И радианы или же градусы тоже надо уточнять.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 09.03.2018, 18:20   #4
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от NetSpace Посмотреть сообщение
в радианах считаются. так что, ты умножай на ПИ и дели на 180
Действительно, про радианы то я и забыл. Только вот воображение у меня работает, и если я умножу на пи, и поделю на 180 - я получу число ещё меньшее, чем изначальное. Так что я предположил, и подтвердил свои предположения, что умножать нужно на 180, а делить на Пи; тут же не сложение, и не умножение, так что перемена мест решает =).

Цитата:
Сообщение от Pavia Посмотреть сообщение
Обычно для этих целий используют актангенс
Подскажите пожалуйста, как с помощью арктангенса мне получить величину от 0 до 359 градусов, имея упомянутый угол прямоугольного треугольника, в одной из четвертей ?
Мне что бы стороны треугольника правильно посчитать - нужно изначально учитывать четверть - что бы сторона a (прилежащий катет) была в нуле градусов заданной четверти с отсчётом по часовой стрелке. Иначе я дальше потеряюсь, где какие углы.
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 09.03.2018 в 22:07.
OmegaBerkut вне форума Ответить с цитированием
Старый 09.03.2018, 21:45   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Код:
#include <math.h>
...
angleA=atan2(coords.Y-centerPos.Y, coords.X-centerPos.X)*180.0/PI;
angleB=90.0-angleA;
angleC=90.0;

И длинный вариант через atan
Код:
a=fabs(coords.X-centerPos.X);
b=fabs(coords.Y-centerPos.Y);
angleA=atan(b/a)*180.0/ M_PI;

    if (x == 0.0)
    {
        if (y == 0.0)
            angleA = 0.0;
        else if (y > 0.0)
            angleA = M_PI/2;
        else
            angleA = -M_PI/2;
    }
    else
    {
        if (x < 0.0)
        {
            if (y > 0.0)
            {
                angleA += M_PI;
            }
            else if (y < 0.0)
            {
                angleA -= M_PI;
            }
            else
            {
                angleA = M_PI;
            }
        }
    }
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 09.03.2018, 22:14   #6
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Pavia, я не могу понять, где у вас учитывается то, что мне необходимо.
Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
что бы сторона a (прилежащий катет) была в нуле градусов заданной четверти с отсчётом по часовой стрелке
Код:
double sideA,sideB,sideC,quarter;
if (coords.X<centerPos.X && coords.Y<=centerPos.Y)
{ // левая верхняя четверть
	sideA=centerPos.X-coords.X;
	sideB=centerPos.Y-coords.Y;
	quarter=0;
} else
if (coords.X>=centerPos.X && coords.Y<centerPos.Y)
{ // правая верхняя четверть
	sideA=centerPos.Y-coords.Y;
	sideB=coords.X-centerPos.X;
	quarter=90;
} else
if (coords.X>centerPos.X && coords.Y>=centerPos.Y)
{ // правая нижняя четверть
	sideA=coords.X-centerPos.X;
	sideB=coords.Y-centerPos.Y;
	quarter=180;
} else
// if (coords.X<=centerPos.X && coords.Y>centerPos.Y)
{ // левая нижняя четверть
	sideA=coords.Y-centerPos.Y;
	sideB=centerPos.X-coords.X;
	quarter=270;
}
sideC=Math.Sqrt(sideA*sideA+sideB*sideB);
double
	// angleA=Math.Acos((sideB*sideB+sideC*sideC-sideA*sideA)/(2*sideB*sideC))*toGrad,
	angleB=Math.Acos((sideA*sideA+sideC*sideC-sideB*sideB)/(2*sideA*sideC))*toGrad+quarter, // quarter'ом я получаю 0-359
	// angleC=Math.Acos((sideA*sideA+sideB*sideB-sideC*sideC)/(2*sideA*sideB))*toGrad;
	relativeAngle=angleB-currentAngle; // необходимый угол поворота относительно текущего угла поворота
if (relativeAngle>180)
	relativeAngle-=360; // это что бы при плавном вращении вертеть с меньшим углом, а это иногда против часовой стрелки
else {}
ResetImage((float)relativeAngle); // это такая функция, которая делает поворот
currentAngle=angleB; // сохраняется текущий угол поворота относительно нуля
Разбиение на все четверти нужно как для учёта прилежащего катета, так и для самих условий, что бы перекрывать стыки четвертей - когда angleA и angleC получают значения NaN, а angleB содержит православные 0 градусов (с учётом четверти это 0-90-180-270).

Я только вот сомневаюсь на счёт этого:
Код:
relativeAngle=angleB-currentAngle;
Возможна ли ситуация, при которой я буду получать отрицательный относительный угол ...
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 09.03.2018 в 22:23.
OmegaBerkut вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти длины высот треугольника, если заданы координаты вершин треугольника. Vadim228 Паскаль, Turbo Pascal, PascalABC.NET 10 30.12.2015 15:45
1) Вычислить углы треугольника со сторонами a,b,c. 2) программа для вычисления значений функций mirovsky Помощь студентам 5 13.01.2015 18:43
Расчёт S и P треугольника через его стороны и/или углы Matrix6993 Общие вопросы Delphi 6 23.02.2012 00:07
Найти внутренние углы треугольника (Pascal) street_spirit Помощь студентам 4 02.03.2010 17:25
Треугольник задан длинами своих сторон: a, b, c. Найти углы треугольника. задача на С++ Wia Помощь студентам 6 13.12.2008 16:13