Теория - Нахождение внутренних углов в многоугольнике

Ответить
Аватара пользователя
mrcnn

Теория - Нахождение внутренних углов в многоугольнике

Сообщение mrcnn »

В декартовой системе координат, образованной окном Windows



Дано: точка 1 (x1, y1) точка 2 (x2, y2) точка 3 (x3, y3) ... точка n (xn, yn)



x1=xn

y1=yn



Замкнутый многоугольник



Найти: все углы многоугольника

Первый угол образован прямыми (x1, y1) - (x2, y2) и (x2, y2) - (x3, y3) .......



N угол образован прямыми (x(n-1), y(n-1)) - (xn, yn) и (xn, yn) - (x1, y1)





Решение:



Длину вектора найти очень просто.

Длина первого вектора

len1 = Math.Sqrt(Math.Abs((x2-x1) * (x2-x1)) + Math.Abs((y2-y1) * l(y2-y1)))

Длина второго вектора

len2 = Math.Sqrt(Math.Abs((x3-x2) * (x3-x2)) + Math.Abs((y3-y2) * l(y3-y2)))







Угол получаем по формуле

(скалярное произведение первого вектора на второй вектор ) / длина первого вектора * длину второго вектора



Скалярное произведение первого вектора на второй

это (x2-x1)*(x3-x2) + (y3-y2)*(y2-y1)



Косинус угла это ( (x2-x1)*(x3-x2) + (y3-y2)*(y2-y1)) / ( len1*len2)



Acos(cos)*180 получаем угол...



Что я не учел? В чем ошибка в рассуждениях и в коде?







Координаты точек хранятся в двух массивах.

XM - координаты x

YM - координата y

tm - длина массивов

Длина массивов одинакова, счетчик совпадает





Код



If tm > 1 Then

For cn = 0 To tm

ReDim Preserve ug(sug)



q1 = cn + 1

If q1 > tm Then

q1 = Math.Abs(tm - Math.Abs(tm - q1) - 1)

End If

q2 = cn + 2

If q2 > tm Then

q2 = Math.Abs(tm - Math.Abs(tm - q2) - 1)

End If



lx = Math.Abs(XM(q1) - XM(cn))

ly = Math.Abs(YM(q1) - YM(cn))

mx = Math.Abs(XM(q2) - XM(q1))

my = Math.Abs(YM(q2) - YM(q1))

z1 = Math.Sqrt(Math.Abs(lx * lx) + Math.Abs(ly * ly))

z2 = Math.Sqrt(Math.Abs(mx * mx) + Math.Abs(my * my))

ug(sug) = (Math.Acos((lx * mx + ly * my) / (z1 * z2))) * 180



MsgBox(CStr(ug(sug)))

sug = sug + 1

Next





для прямоугольного треугольника выдача: 115, 164, 280

280 вполне логичное значение т.к 360-280=90

115 и 164 как получены не понимаю значит где-то ошибка

Где я ошибся?
Аватара пользователя
Altair86

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение Altair86 »

Цитата mrcnn:



ug(sug) = (Math.Acos((lx * mx + ly * my) / (z1 * z2))) * 180
Теория - Нахождение внутренних углов в многоугольнике




Попробуй поделить на пи.

ug(sug) = (Math.Acos((lx * mx + ly * my) / (z1 * z2))) * 180/3,1415926

В код не очень врубился, торможу( Если других ошибок нет, программка должна вроде на невыпуклых многоугольниках подглючивать.
Аватара пользователя
Coutty

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение Coutty »

Цитата mrcnn:



280 вполне логичное значение т.к 360-280=90
Теория - Нахождение внутренних углов в многоугольнике




Извините, конечно, но проверьте на калькуляторе Изображение




Цитата mrcnn:



len1 = Math.Sqrt(Math.Abs((x2-x1) * (x2-x1)) + Math.Abs((y2-y1) * l(y2-y1)))
Теория - Нахождение внутренних углов в многоугольнике




Зачем брать абсолютное значение, если при возведении в квадрат всё равно положительное число получается? Непонятно также, что это за палочка перед второй скобкой с игреками. Наверное, опечатка?



А что, если для вычисления угла воспользоваться теоремой косинусов? Просто я не понял про скалярное произведение векторов, да и вообще...

cos (между b и c) = (b^2 + c^2 - a^2) / 2bc.

Правда тут ещё придётся длину a вычислять (по концам векторов b и с, разумеется).
Аватара пользователя
mrcnn

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение mrcnn »

Графически задача выглядит так:

Изображение



Изображение





Отредактировано:



Хм.. Деление на пи рулезно сработало. Объясните, почему пришлось еще делить на пи?
Аватара пользователя
mrcnn

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение mrcnn »

mrcnn, а ведь если б по ссылке сходил из соседней темы


Цитата Admiral:



mrcnn, MSDN нету?

...

Math.Acos Method
VBA - Visual Basic 2008




то там бы нашёл бы рулёзную формулу


Цитата Math.Acos Method (System):



Remarks



Multiply the return value by 180/Math.PI to convert from radians to degrees.
>>




Потому что Pi это 180 градусов, а 3.14... это в радиальной мере.

И выходит пропорция



Код:

Код: Выделить всё

Pi это 180 градусов  3.14... радиан
         Х градусов          Х радиан
Х градусов=180 градусов*Х Радиан/3.14... радиан (то есть Pi)
Аватара пользователя
mrcnn

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение mrcnn »

Цитата:



Multiply the return value by 180/Math.PI to convert from radians to degrees



По ссылке из соседней темы я сходил, увидел только то, что надо умножить на 180 как раз в той самой ремарке, которые вы откопировали

но я не увидел еще, что надо разделить на Math.PI



Сходил еще раз. Не увидел, потому что Math.PI было выделено ссылкой. Я прочитал все, что было до ссылки.



В школе, к сожалению, не научили переводить из радианов в градусы Изображение MSDN бы и не понадобился тогда.
Аватара пользователя
Admiral

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение Admiral »

mrcnn, теперь на примере пропорции ясность есть?

Да ещё по коду, я бы сделал одну процедуру которая считает угол между отрезками, координаты точек которых известно, а потом бы вызвал эту процедуру n раз, на количество вершин многоугольника.
Аватара пользователя
Admiral

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение Admiral »

Цитата:



mrcnn, теперь на примере пропорции ясность есть?



Да. Спасибо.
Аватара пользователя
mrcnn

Re: Теория - Нахождение внутренних углов в многоугольнике

Сообщение mrcnn »

Еще возможен альтернативный способ:

Dim N As Integer 'число углов/сторон

Dim XM() As Single 'координаты Х вершин

Dim YM() As Single 'координаты Y вершин

Dim fi() As Single ' угол такой) объяснение ниже

Dim sinus As Single 'синус этого угла

Dim cosinus As Single ' косинус его же

Dim len As Single 'длины сторон многоугольника

Dim angle() As Single ' то, что нам надо-- углы многоугольника

Dim i As Byte 'переменная цикла, юзаем везде где надо

Private Sub

' здесь у нас ввод N

'после чего задаем длины массивов

ReDim XM(0 to N+1)

ReDim YM(0 to N+1)

ReDim fi(0 to N)

ReDim Angle(1 to N)

' здесь у нас ввод кооординат вершин от 1-й до N-й

' внимание! вершины нумеруем по часовой стрелке

XM(0)=XM(N)

XM(N+1)=XM(1)

YM(0)=YM(N)

YM(N+1)=YM(1)

'0-я и (N+1)-я вершины будут нужны



'Далее вычисляется угол между i-й стороной и положительным

'направлением оси Ох. Угол отсчитывается против часовой стрелки

' это то самое fi

For i= 0 To N

'вычисляем длину i-й стороны

'i-я сторона идет от i-й вершины к (i+1)-й

'вот нам и понадобились 0-я и N+1-я вершины

len=Sqr (((XM(i)-XM(i+1))^2+(YM(i)-YM(i+1))^2)

'находим синус и косинус вычисляемого угла

sinus= (YM(i+1)-YM(i))/len

cosinus= (XM(i+1)-XM(i))/len

' Дальше считаем сам угол

If sinus>=0 Then

fi(i) =acos(cosinus)

Else

fi(i)=2*Pi-acos(cosinus)

EndIf

Next i



For i =1 to N

angle(i)= Pi+ (fi(i)-fi(i-1))

'здесь понадобилась 0-я сторона

If angle(i)
Ответить

Вернуться в «Программирование и базы данных»