В декартовой системе координат, образованной окном 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: Теория - Нахождение внутренних углов в многоугольнике
Цитата 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
В код не очень врубился, торможу( Если других ошибок нет, программка должна вроде на невыпуклых многоугольниках подглючивать.
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: Теория - Нахождение внутренних углов в многоугольнике
Цитата 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 и с, разумеется).
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
Re: Теория - Нахождение внутренних углов в многоугольнике
mrcnn, а ведь если б по ссылке сходил из соседней темы
Цитата Admiral:
mrcnn, MSDN нету?
...
то там бы нашёл бы рулёзную формулу
Цитата Math.Acos Method (System):
Remarks
Multiply the return value by 180/Math.PI to convert from radians to degrees.
Потому что Pi это 180 градусов, а 3.14... это в радиальной мере.
И выходит пропорция
Код:
Цитата 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: Теория - Нахождение внутренних углов в многоугольнике
Цитата:
Multiply the return value by 180/Math.PI to convert from radians to degrees
По ссылке из соседней темы я сходил, увидел только то, что надо умножить на 180 как раз в той самой ремарке, которые вы откопировали
но я не увидел еще, что надо разделить на Math.PI
Сходил еще раз. Не увидел, потому что Math.PI было выделено ссылкой. Я прочитал все, что было до ссылки.
В школе, к сожалению, не научили переводить из радианов в градусы
MSDN бы и не понадобился тогда.
Multiply the return value by 180/Math.PI to convert from radians to degrees
По ссылке из соседней темы я сходил, увидел только то, что надо умножить на 180 как раз в той самой ремарке, которые вы откопировали
но я не увидел еще, что надо разделить на Math.PI
Сходил еще раз. Не увидел, потому что Math.PI было выделено ссылкой. Я прочитал все, что было до ссылки.
В школе, к сожалению, не научили переводить из радианов в градусы
MSDN бы и не понадобился тогда.-
Admiral
Re: Теория - Нахождение внутренних углов в многоугольнике
mrcnn, теперь на примере пропорции ясность есть?
Да ещё по коду, я бы сделал одну процедуру которая считает угол между отрезками, координаты точек которых известно, а потом бы вызвал эту процедуру n раз, на количество вершин многоугольника.
Да ещё по коду, я бы сделал одну процедуру которая считает угол между отрезками, координаты точек которых известно, а потом бы вызвал эту процедуру n раз, на количество вершин многоугольника.
-
Admiral
Re: Теория - Нахождение внутренних углов в многоугольнике
Цитата:
mrcnn, теперь на примере пропорции ясность есть?
Да. Спасибо.
mrcnn, теперь на примере пропорции ясность есть?
Да. Спасибо.
-
mrcnn
Re: Теория - Нахождение внутренних углов в многоугольнике
Еще возможен альтернативный способ:
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)
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)