|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Теория - Нахождение внутренних углов в многоугольнике |
|
Теория - Нахождение внутренних углов в многоугольнике
|
Ветеран Сообщения: 1404 |
В декартовой системе координат, образованной окном 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 |
Новый участник Сообщения: 15
|
Профиль | Отправить PM | Цитировать Цитата mrcnn:
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 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Кот Ти Сообщения: 7318
|
Профиль | Отправить PM | Цитировать Цитата mrcnn:
![]() Цитата mrcnn:
А что, если для вычисления угла воспользоваться теоремой косинусов? Просто я не понял про скалярное произведение векторов, да и вообще... cos (между b и c) = (b^2 + c^2 - a^2) / 2bc. Правда тут ещё придётся длину a вычислять (по концам векторов b и с, разумеется). |
||
Отправлено: 18:50, 31-05-2008 | #3 |
Ветеран Сообщения: 1404
|
Профиль | Отправить PM | Цитировать Графически задача выглядит так:
Отредактировано: Хм.. Деление на пи рулезно сработало. Объясните, почему пришлось еще делить на пи? |
Последний раз редактировалось mrcnn, 31-05-2008 в 19:44. Отправлено: 19:04, 31-05-2008 | #4 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать mrcnn, а ведь если б по ссылке сходил из соседней темы
Цитата Admiral:
Цитата Math.Acos Method (System):
И выходит пропорция |
|||
Последний раз редактировалось Admiral, 31-05-2008 в 20:07. Отправлено: 19:47, 31-05-2008 | #5 |
Ветеран Сообщения: 1404
|
Профиль | Отправить PM | Цитировать Цитата:
но я не увидел еще, что надо разделить на Math.PI Сходил еще раз. Не увидел, потому что Math.PI было выделено ссылкой. Я прочитал все, что было до ссылки. В школе, к сожалению, не научили переводить из радианов в градусы ![]() |
|
------- Отправлено: 20:05, 31-05-2008 | #6 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать mrcnn, теперь на примере пропорции ясность есть?
Да ещё по коду, я бы сделал одну процедуру которая считает угол между отрезками, координаты точек которых известно, а потом бы вызвал эту процедуру n раз, на количество вершин многоугольника. |
Отправлено: 20:10, 31-05-2008 | #7 |
Ветеран Сообщения: 1404
|
Профиль | Отправить PM | Цитировать Цитата:
|
|
------- Отправлено: 20:23, 31-05-2008 | #8 |
Новый участник Сообщения: 15
|
Профиль | Отправить 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 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
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 |
|