Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 838

/ вопрос решён /

Здравствуйте, эксперты!
Как определить по часовой стрелке или против? распологаются координаты вершин многоугольника, записанные в массив TPoint.

Данный вопрос один из этапов решения вопроса №5 834

Pest Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Pest (статус: Посетитель)
Вопрос отправлен: 22 декабря 2011, 07:50
Состояние вопроса: решён, ответов: 1.

Ответ #1. Отвечает эксперт: Егор

Здравствуйте, Pest!
Не надо изобретать велосипед, когда всё давно придумано за нас. Берём хорошую книгу по компьютерной графике и читаем. Очень хорошие книги были выпущены ещё в 70-80-ых годах. Да и сейчас бывают очень даже неплохие книги.

Теперь по теме. Если многоугольник выпуклый, то достаточно проверить любые три подряд идущие точки:

...
var
  x, y : array [1..N] of extended;
  dx1, dx2, dy1, dy2, r : extended;
...
  dx1 := x[2] - x[1];
  dx2 := x[3] - x[2];
  dy1 := y[2] - y[1];
  dy2 := y[3] - y[2];
  r := dx1*dy2 - dx2*dy1;
  if r > 0 then
    writeln('Против часовой стрелки')
  else if r < 0 then
    writeln('По часовой стрелке')
  else
    writeln('Отрезки лежат на одной прямой');
...

Для более сложных многоугольников (а также для решения вопроса 5834) ищем книгу(-и) по компьютерной графике и там уже находим ответы.

Ответ отправил: Егор (статус: 10-ый класс)
Время отправки: 22 декабря 2011, 19:38
Оценка за ответ: 3


Мини-форум вопроса

Всего сообщений: 9; последнее сообщение — 26 декабря 2011, 12:30; участников в обсуждении: 4.
Вадим К

Вадим К (статус: Академик), 22 декабря 2011, 12:20 [#1]:

Это не всегда возможно. Говорить о порядке точек "по часовой или против" можно только в том случае, если есть опорная точка. Такой точкой может стать центр фигуры. То есть, банально считаем среднее арифметическое по каждой координате и получаем точку. Теперь берем две точки (соседние) и считаем угол (это уже школьная геометрия). А по нему уже будет понятно.
Галочка "подтверждения прочтения" - вселенское зло.
Pest

Pest (статус: Посетитель), 22 декабря 2011, 14:42 [#2]:

Да если брать за опорную точку центр, то не всегда возможно, а вот если взять самую северную т.е. с самым большим значением Х.
Вот написал вроде получилось)
function KontNorm(Points : array of TPoint; const Col : integer): boolean;
var
dx1,dy1,dx2,dy2,s,a,u1,u2,max:real;
i,imax:integer;
begin
{определение точки с наибольшм значением Х}
 max:=0;
 for i := 1 to col do
 begin
  if Points[i-1].X>max then begin
   imax:=i;
   max:=Points[i-1].X;
  end;
 end;
{Расчеты}
 if imax=col then begin
 dx1:= Points[0].X-Points[imax-1].X;
 dy1:= Points[0].Y-Points[imax-1].Y;
 end else begin
 dx1:= Points[imax].X-Points[imax-1].X;
 dy1:= Points[imax].Y-Points[imax-1].Y;
 end;
 if imax=1 then begin
 dx2:= Points[col-1].X-Points[imax-1].X;
 dy2:= Points[col-1].Y-Points[imax-1].Y;
 end else begin
 dx2:= Points[imax-2].X-Points[imax-1].X;
 dy2:= Points[imax-2].Y-Points[imax-1].Y;
 end;
{определение директионного угла №1}
 s:=sqrt(sqr(dx1)+sqr(dy1));//расстояние  до следующей точки
 a:=RadToDeg(arccos(dx1/s));
 if dy1>=0 then begin //определение угла
  u1:=a;
 end else begin
  u1:=360-a;
 end;
{определение директионного угла №2}
 s:=sqrt(sqr(dx2)+sqr(dy2));//расстояние  до предыдущей точки
 a:=RadToDeg(arccos(dx2/s));
 if dy2>=0 then begin  //определение угла
  u2:=a;
 end else begin
  u2:=360-a;
 end;
{результат}
 if u2>u1 then begin
  KontNorm:=True;//По часовой
 end else begin
  KontNorm:=False;//Против часовой
 end;
end;
Pest

Pest (статус: Посетитель), 22 декабря 2011, 14:44 [#3]:

посмотрите пожалуйста опытным глазом может я ошибаюсь где?
Егор

Егор (статус: 10-ый класс), 22 декабря 2011, 19:42 [#4]:

Цитата (Вадим К):

Это не всегда возможно. Говорить о порядке точек "по часовой или против" можно только в том случае, если есть опорная точка.

это почему это? даны три точки. они лежат не на прямой. из вопроса следует, что мы имеем дело с двухмерной системой координат (не 3D). тогда, при заданном порядке обхода точек, мы всегда можем сказать, по часовой или против часовой идут эти точки.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
Pest

Pest (статус: Посетитель), 23 декабря 2011, 07:31 [#5]:

про функцию кто нибудь что н будь скажет или нет?

23 декабря 2011, 15:56: Статус вопроса изменён на решённый (изменил автор вопроса — Pest)

Вадим К

Вадим К (статус: Академик), 23 декабря 2011, 16:25 [#6]:

to Егор:
В случае трех точек - да (если конечно они не равны по координатам), да возможно. Но вот как точек стает 4… сразу наступет неопределенность. например такие точки (0,0), (5,5), (0,10), (5,15).
Однозначно можно сказать только для точек выпуклого многоугольника.

to Pest: для меня почему то "самая северная" это вверху (то есть с самой большой координатой Y). Для австралийцев это конечно будет по другому. Но вот что бы справа...
А сам код что то делает. Но если предпосылка неверная, то…
Галочка "подтверждения прочтения" - вселенское зло.
Pest

Pest (статус: Посетитель), 26 декабря 2011, 08:38 [#7]:

to Вадим К: все правильно в геодезической системе Y вверху, в математической системе X вверху(как и в ГИС на которую я ориентируюсь в своем проекте):)))
Вадим К

Вадим К (статус: Академик), 26 декабря 2011, 11:50 [#8]:

Цитата (Pest):

математической системе X вверху

у математиков как раз по умолчанию Y вверху, X справа. (конечно, математики любители абстракций, и может быть как угодно, но об этом обычно предварительно договариваются:) ).
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 26 декабря 2011, 12:30 [#9]:

В Австралии всё равно карты читать не умеют. Тахеометрический ход, чтоли?
виконання програми розпочинається з того самого мiсця, де призупинилося.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:46
Выполнено за 0.03 сек.