Вычислите угол треугольника, когда даны 3 точки

у меня есть 3 точки ((x, y), (x', y'), (x'', y'')) и я хочу найти угол в 3 точках, мне также нужно получить точку при наличии угол и 2 другие точки (но это не должно быть проблемой)

если это поможет - я работаю с С#


person n3rdpr0gr4mm3r    schedule 16.07.2011    source источник
comment
вы можете использовать тот факт, что xy = |x||y|cos(x^y) (x, y -- векторы, xy -- их скалярное произведение)   -  person Vlad    schedule 16.07.2011
comment
stackoverflow.com/questions/4879961/› Посмотрите на этот вопрос   -  person Mark Segal    schedule 16.07.2011


Ответы (3)


Для общего непрямоугольного треугольника вам понадобится так называемый закон косинусов. Это позволяет вычислить внутренние углы в каждом углу треугольника, учитывая длины каждой стороны. Вы можете рассчитать длину каждой стороны, используя равенство Пифагора.

Вторая часть вашего вопроса четко не указана.

person David Heffernan    schedule 16.07.2011
comment
у меня непрямой треугольник - я знаю 3 точки - 2 точки фиксированы и 1 точка - это направление, куда летит один объект. поэтому я вычисляю угол между этими 3 точками. мне нужно поразить объект, который движется в указанном направлении (все имеет одинаковую скорость, поэтому мне нужно только смотреть, чтобы угол был ниже 90 градусов). поэтому я могу сказать, что альфа и бета должны быть под одним и тем же углом. когда у меня есть угол, мне нужно только рассчитать точку, в которой я должен снять свой третий объект. - person n3rdpr0gr4mm3r; 17.07.2011
comment
и это сводит меня с ума; вот что у меня на самом деле есть: ‹br /›‹code› // просто чтобы сделать его короче double angle = Math.Acos(dotprod / Math.Sqrt(len1sq * len2sq)); len1sq = Math.Sqrt(len1sq); len1sq = (целое)len1sq; int новыйX = 0, новый Y = 0; if (b.x › a.x) { newX = b.x - (int)len1sq; } if (b.x ‹ a.x) { newX = b.x + (int)len1sq; } if (b.y › a.y) { newY = b.y - (int)len1sq; } if (b.y ‹ a.y) { newY = b.y + (int)len1sq; } вернуть новую точку(newX, newY); <код> - person n3rdpr0gr4mm3r; 17.07.2011

Прочитайте следующее: http://en.wikipedia.org/wiki/Trigonometric_functions и http://jwbales.us/precal/part6/part6.2.html

потому что A = (b ^ 2 + c ^ 2 - a ^ 2) / ( 2 bc )

потому что B знак равно ( а ^ 2 + с ^ 2 - b ^ 2 ) / ( 2 ас )

потому что C = ( a ^ 2 + b ^ 2 - c ^ 2 ) / ( 2 ab )

затем возьмите arccos для каждого из полученных значений, чтобы найти угол.

Изучите триггер, проведите исследование и преобразуйте приведенные выше уравнения в код.

person Null    schedule 16.07.2011
comment
почему вы повторяете формулу 3 раза? Один раз достаточно. - person David Heffernan; 17.07.2011

Ну, проще всего было бы использовать скалярное произведение:

double dotprod = (x'' - x)*(x' - x) + (y'' - y)*(y' - y);
double len1 = sqrt((x' - x) * (x' - x) + (y' - y) * (y' - y));
double len2 = sqrt((x'' - x) * (x'' - x) + (y'' - y) * (y'' - y));
double angle = acos(dotprod/(len1*len2));

Это должно быть быстрее, чем использование закона косинусов.

Редактировать:
Мы можем опустить один sqrt, если делаем так:

double dotprod = (x'' - x)*(x' - x) + (y'' - y)*(y' - y);
double len1squared = (x' - x) * (x' - x) + (y' - y) * (y' - y);
double len2squared = (x'' - x) * (x'' - x) + (y'' - y) * (y'' - y);
double angle = acos(dotprod/sqrt(len1squared*len2squared));

Этот расчет в основном такой же, как у @David.

person Vlad    schedule 16.07.2011
comment
какова «средняя» точка в этой формуле? потому что у меня 2 конечные точки и 1 точка посередине - person n3rdpr0gr4mm3r; 17.07.2011
comment
Это не будет быстрее. Звонки sqrt причинят боль. Вы не делаете те с законом косинуса. Если бы вас беспокоила скорость, вы бы переписали это всего одним вызовом sqrt, но даже в этом случае закон косинусов будет быстрее. Наконец, не могли бы вы объяснить обоснование этого метода. В противном случае это выглядит просто волшебством для OP. - person David Heffernan; 17.07.2011
comment
Угол измеряется в точке (x, y). - person Vlad; 17.07.2011
comment
@David: как ты собираешься вычислять 2bc по закону косинусов без sqrt? - person Vlad; 17.07.2011
comment
@Влад Влад Ах, поймал меня там! Однако одного sqrt достаточно. Я предполагаю, что эта волшебная формула, которую вы создаете, эквивалентна закону косинусов, поскольку len1 * len2 кажется не более чем bc, а затем есть acos. - person David Heffernan; 17.07.2011
comment
@David: действительно, мы с тобой вычисляем одни и те же числители и знаменатели, только у меня на одно умножение меньше. Ваше будет моим, если подставить значения координат и упростить. - person Vlad; 17.07.2011
comment
@David: как математик я утверждаю, что закон косинусов и скалярное произведение эквивалентны :-) - person Vlad; 17.07.2011
comment
мне нужно вычислить это только один раз, поэтому производительность не имеет большого значения - person n3rdpr0gr4mm3r; 17.07.2011
comment
@ Влад Как математик, я сейчас потрачу некоторое время на то, чтобы понять, почему ваше утверждение верно. - person David Heffernan; 17.07.2011
comment
@David: я использую только x\dot y = |x||y|cos(x^y) - person Vlad; 17.07.2011
comment
Я предполагаю, что угол, который выходит, в радианах, верно? хорошо, мне нужно только повернуть его сейчас х.х - person n3rdpr0gr4mm3r; 17.07.2011
comment
Есть ли способ связаться с вами, Влад, чтобы решить эту проблему как можно быстрее? :/ - person n3rdpr0gr4mm3r; 17.07.2011
comment
@kafioin: в stackoverflow есть чат: chat.stackoverflow.com/rooms/7/c - person Vlad; 17.07.2011
comment
теперь у меня есть 2 точки и угол, и я ищу вторую конечную точку. мне нужно только преобразовать уравнение, но что противоположно acos? - person n3rdpr0gr4mm3r; 17.07.2011
comment
двойной dotDivLen = Math.Cos(угол); // = dotprod / sqrt(len1*len2) --------- len1sq = (endP1.X - aP.X) * (endP1.X - aP.X) + (endP1.Y - aP.Y ) * (конец P1.Y - aP.Y); ------ двойной sol = dotDivLen * Math.Sqrt(len1sq); // = dotprod/sqrt(len2) ------ это то, что я на самом деле получил, но я до сих пор не знаю, как я могу получить x/y :/ - person n3rdpr0gr4mm3r; 17.07.2011