Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Теория - Нахождение внутренних углов в многоугольнике

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

Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


В декартовой системе координат, образованной окном 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 как получены не понимаю значит где-то ошибка
Где я ошибся?

Отправлено: 17:08, 31-05-2008

 

Аватара для Altair86

Новый участник


Сообщения: 15
Благодарности: 2

Профиль | Отправить PM | Цитировать


Цитата 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
В код не очень врубился, торможу( Если других ошибок нет, программка должна вроде на невыпуклых многоугольниках подглючивать.

-------
Будь проклят тот день, когда обезьяна слезла с дерева и научилась говорить...


Последний раз редактировалось Altair86, 31-05-2008 в 18:48.

Это сообщение посчитали полезным следующие участники:

Отправлено: 18:37, 31-05-2008 | #2



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

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для Coutty

Кот Ти


Сообщения: 7318
Благодарности: 1204

Профиль | Отправить PM | Цитировать


Цитата 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 и с, разумеется).

Отправлено: 18:50, 31-05-2008 | #3


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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





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

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

Последний раз редактировалось mrcnn, 31-05-2008 в 19:44.


Отправлено: 19:04, 31-05-2008 | #4


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


mrcnn, а ведь если б по ссылке сходил из соседней темы
Цитата Admiral:
mrcnn, MSDN нету?
...
Math.Acos Method »
то там бы нашёл бы рулёзную формулу
Цитата 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)

Последний раз редактировалось Admiral, 31-05-2008 в 20:07.

Это сообщение посчитали полезным следующие участники:

Отправлено: 19:47, 31-05-2008 | #5


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


Цитата:
Multiply the return value by 180/Math.PI to convert from radians to degrees
По ссылке из соседней темы я сходил, увидел только то, что надо умножить на 180 как раз в той самой ремарке, которые вы откопировали
но я не увидел еще, что надо разделить на Math.PI

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

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

-------
Ehhh.. what's up, doc?..


Отправлено: 20:05, 31-05-2008 | #6


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


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

Отправлено: 20:10, 31-05-2008 | #7


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


Цитата:
mrcnn, теперь на примере пропорции ясность есть?
Да. Спасибо.

-------
Ehhh.. what's up, doc?..


Отправлено: 20:23, 31-05-2008 | #8


Аватара для Altair86

Новый участник


Сообщения: 15
Благодарности: 2

Профиль | Отправить PM | Цитировать


Еще возможен альтернативный способ:
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)<0 Then angle(i)= angle(i)+2*Pi
angle(i)=angle(i)*180/Pi
Next i
'<...> здесь можем вывести значения углов
'массив углов можно не создавать,тогда
'вывод внутри последнего цикла делаем
End Sub

-------
Будь проклят тот день, когда обезьяна слезла с дерева и научилась говорить...


Отправлено: 14:51, 01-06-2008 | #9



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Теория - Нахождение внутренних углов в многоугольнике

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
C/C++ - [решено] Нахождение обратной матрицы методом Гаусса и рассширенной матрицы D.Y. Программирование и базы данных 64 06-05-2011 22:59
C/C++ - Нахождение чётных элементов в столбцах матрицы ShadowMas Программирование и базы данных 9 04-04-2009 10:21
visual basic||нахождение минимума функции методом покоординатного градиентного спуска bezumes Программирование и базы данных 3 09-05-2007 02:33
Нахождение сервера лицензий w2k3 SergOst Microsoft Windows NT/2000/2003 3 09-11-2006 14:59
*Теория* | Нахождение коэффициентов полного уравнения 4 степени mrcnn Программирование и базы данных 5 21-09-2006 13:58




 
Переход