Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2003.03.24;
Скачать: [xml.tar.bz2];

Вниз

Помогите с расчетом координат.   Найти похожие ветки 

 
Ssergy   (2002-11-07 18:32) [0]

Мастера, помогите пожалуйста.
Есть замкнутый контур, заданный точкам.
Необходимо получит контур, находящийся внутри данного, на расстоянии k от каждой из сторон. (т.е надо получить пропорционально уменьшеный контур внутри данного).
Хоть какие - либо идеи please.
Заранее спасибо.


 
Ketmar   (2002-11-07 19:31) [1]

элементарно, Ватсон. %-) уменьшить размер исходного контура на необходимую величину.

Satanas Nobiscum! 07-Nov-XXXVII A.S.


 
Ssergy   (2002-11-07 20:23) [2]

Если уменьшать координаты контура на необходимую величину, новый контур не будет находиться внутри заданного, он смститься, а необходимо, что-бы он находился внутри.


 
ZrenBy   (2002-11-07 20:30) [3]

Выбираешь систему координат.
Берешь точку (x1,y1)
находишь два вектора из нее к соседним точкам
определяешь вектор-биссектрису к расчетной точке
находишь длину этого вектора, так чтобы расчетная точка
была на заданном удалении
Определяешь координаты расчетной точки.

Фу. кажется так, только формулы надо вывести.


 
LestatRE   (2002-11-07 21:24) [4]

Example
__________
/\ /\
/ \ / \
/ \ / \
/ \ / \
/________\/________\
\ /\ /
\ / \ /
\ / \ /
\ / \ /
\/________\/

Пересечение прямых внутри фигуры вызывает центральную точку.
Если отмерить точки на этих прямых, равноудаленные внутрь
от границ многоугольника и соединить их между собой прямыми, то получится необходимый результат : фигура, меньшая исходной на значение величины k. Однако действует этот способ не везде. В остальном, я думаю, можно разобраться .


 
Ssergy   (2002-11-07 23:25) [5]

ZrenBy пожалуйста, если можно поподробнее.
По моему в точке x1,y1 метод работать не будет, т.к вектор- бисектриса буде напралена вне контура.
/------
/ |
\ |
\ |
\ |
(x1,y1). |
/ |
/ |
/_______|
\-------/


 
Alex44   (2002-11-08 01:59) [6]

Esli contur ne vypuklyj, ne ochen" ponyatno, chto est" "vnutri".

1 2
__________
\ /
\ /
\ /
\ /
\/
/\
/__\
3 4

Esli eto resheno (skazhem, contur orientirovan), to ostal"noe elementarno: kazhdaya pryamaya sdvigaetsya po perpendiculyaru na nuzhnoe rasstoyanie (sm. freshman calculus), a potom vershiny nahodyatsya, kak tochki peresecheniya sosednih reber (linejnaya algebra).


 
Ketmar   (2002-11-08 09:45) [7]

господа, вы что, с дубов попадали? я же уже ответил!
>Если уменьшать координаты контура на необходимую величину, новый контур не будет находиться внутри заданного, он сместится, а необходимо, что-бы он находился внутри.
вы чего, совсем думать не желаете? а принять за начало координат центр вашего первичного контура моральные принципы не позволяют? начало координат есмь штука неприкосновенная, да?
единственно, мой ответ подразумевал, что "контур" - это "полигон". причем неважно, какой: convex или concave. чем отличается полигон от фигуры Alex"а44, надеюсь, все знают.

Satanas Nobiscum! 08-Nov-XXXVII A.S.


 
Ssergy   (2002-11-08 09:58) [8]

А как найти центр совершенно произвольного контура???


 
Ketmar   (2002-11-08 11:23) [9]

извиняюсь. с дуба упал я. мой метод работает только для convex polygons. %-( недодумал.
вношу поправку: если полигон есть concave, то нужно его побить на кучу convex"ов, потом для каждого применить мой алгоритм (немного усложненный), потом все нарисовать (естественно, не рисуя ребра-"разбиватели").
под "центром" я, естественно, имел в виду центр масс.
более подробно описывать лень...

Satanas Nobiscum! 08-Nov-XXXVII A.S.


 
AlexT1000   (2002-11-08 11:56) [10]

берешь выкачиваешь G32 http://g32.org там среди работы с полигонами есть функция Grow . и будет тебе счастье.


 
Alex44   (2002-11-08 19:59) [11]

> Ketmar
Chestno govorya, mne, kak mathematicu, ochen" lyubopytno, chto takoe polygon (esli on not convex). Prosto, ya schitayu sebya professionalom (v mathematice, ne v programmirovanii), i nedavno ya prisutstvoval na zasedanii redcollegii nekogo Francusskogo analiga nashego Quant"a, gde neskol"ko nehilyh (poverte) mathematicov pytalis" opredelit", chto takoe polygon...


 
Ketmar   (2002-11-08 20:41) [12]

2Alex44:
в данном случае ПОЛИГОН - это скорее программерский термин, нежели математический. %-) полигон - это контур, в котором ребра не имеют пересечений.

Satanas Nobiscum! 08-Nov-XXXVII A.S.


 
Alex45   (2002-11-10 14:21) [13]

Sserg, метод с биссектрисой - весьма дельно предложен. Ведь бывает же и биссектриса тупого угла, не так ли :).

Alex44, не надо умничать, пожалуйста, Вы не единственный математик здесь. Естественно, имелся в виду контур без самопересечений (выпуклость, кстати, это нечто другое), и метод, предложенный уважаемым ZrenBy эффективнее (не надо находить прямые, а затем их точки пересечения. Сразу - вершины нового контура!).
PS Я бы, на Вашем месте, не спешил называть себя профессионалом в математике. Кстати, Вы что заканчивали?


 
Song   (2002-11-10 18:47) [14]

А может просто InflateRect()?


 
Alex44   (2002-11-10 19:45) [15]

To Alex45

Ya smotryu, tut uzhe pereshli na lichnosti. Kstati, ya zakanchival LGU i aspiranturu v LOMI.


> Есть замкнутый контур, заданный точкам.


Tem samym, lyuboj algorithm dolzhen by snachala opredelit" (po tochkam), chto contour ne imeet samoperesechenij, a potom ego orientirovat", chtoby otlichit" vnuttrennost" ot vneshnosti. (Zadazha reshabel"naya, no tozhe ne s naletu.)

V smysle skorosti, ya ne uveren, chto vychislenie dlin bissectriss na osnove predvaritel"no vychislennyh uglov bystree, chem reshenie linejnyh system.


 
Alex45   (2002-11-11 07:27) [16]

Alex44, найти направляющий вектор биссектрисы по двум направляющим углов - элементарно (это школа!). А уж затем привести его длину к необходимой - это, простите, вовсе теорема Пифагора.
Теперь сравним.
Ваш метод (В):
1. Найти перпендикуляр. Далее параллельный перенос ребра контура по этому вектору.

Метод ZrenBy (Z):
1. Найти вектор биссектрисы, затем привести его к нужной длине.

(В):
2. Решить N систем лин. ур-ий, где N - кол-во рёбер, тем самым получив точки нового контура.

(Z, В):
3. Соединить получивиеся точки. Ч. и т.д.

И никаких систем...

Что по вашему проще?
К тому же, я думаю, не надо говорить о том, что векторный метод предпочтительнее, нежели координатный. У нас при поступлении за задачу решённую координатным методом снимали баллы, за слабую способность к производству мысли...

С уважением, Колобов.


 
Fenik   (2002-12-01 10:57) [17]

Попробовал написать процедуру по методу Alex44. Получилось отчасти. Проц-а работает только для приведённого случая. Для многих других случаев работает неверно. Может кто-нибудь попробует доделать (я тоже попытаюсь - задача интересная и полезная).


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Math;

type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{function Len(L: TLine): Integer;
begin
Result := Round(Sqrt(Sqr(L.P2.x - L.P1.x) + Sqr(L.P2.y - L.P1.y)));
end;
}
type TPoints = array of TPoint;
TLine = record
P1, P2: TPoint;
end;

function Inside(const P: TPoints; Size: Integer): TPoints;

function GetCrossLine(const A, B: TLine; var Cross: TPoint): Boolean;
const Epsilon = 1e-8; // выставлять в зависимости от точности Double
var dx1, dy1, dx2, dy2, D: Integer;
P2: Double;
begin
Result := False;
dx1 := A.P2.X - A.P1.X;
dy1 := A.P2.Y - A.P1.Y;
dx2 := B.P2.X - B.P1.X;
dy2 := B.P2.Y - B.P1.Y;
D := dy1*dx2 - dy2*dx1;
if Abs(D) < Epsilon then Exit;
P2 := (dy1*(A.P1.X - B.P1.X) - dx1*(A.P1.Y - B.P1.Y))/D;
Cross.X := Round(B.P1.X + dx2*P2);
Cross.Y := Round(B.P1.Y + dy2*P2);
Result := True;
end;

function GetParallelLine(const Line: TLine; i: Integer): TLine;
var ASin, ACos: Extended;
begin
SinCos(ArcTan2(Line.P2.X - Line.P1.X, Line.P2.Y - Line.P1.Y)+Pi/2*i, ASin, ACos);
with Result do begin
P1.X := Round(Line.P1.X + Size*ACos);
P1.Y := Round(Line.P1.Y + Size*ASin);
P2.X := Round(Line.P2.X + Size*ACos);
P2.Y := Round(Line.P2.Y + Size*ASin);
end;
end;

var i, l: Integer;
L1, L2, L3: TLine;
begin
l := High(P);
if l < 2 then Exit;
SetLength(Result, L + 1);
L1.P1 := P[0];
L1.P2 := P[l];
L1 := GetParallelLine(L1, 1);
L3 := L1;
for i := 0 to l-1 do begin
L2.P1 := P[i];
L2.P2 := P[i + 1];
L2 := GetParallelLine(L2, 1);
GetCrossLine(L2, L3, Result[i]);
L3 := L2;
end;
GetCrossLine(L1, L3, Result[l]);
end;

procedure TForm1.FormPaint(Sender: TObject);
var P: TPoints;
begin
SetLength(P, 3);
P[0] := Point(200, 100);
P[1] := Point(300, 300);
P[2] := Point(100, 200);
with Canvas do begin
Brush.Style := bsClear;
Pen.Color := clRed;
Pen.Width := 2;
Polygon(P);
Pen.Color := clBlue;
Polygon(Inside(P, 30));
end;
end;

end.


 
Alex45   (2002-12-03 06:50) [18]

А конкретнее? Для каких не работает?


 
Alex45   (2002-12-03 08:10) [19]

А если вот так?


 
Alex45   (2002-12-03 08:18) [20]

for i:=2 to Counter do
begin
Vect1[1]:=Points[i+1,1]-Points[i,1]; //x-coordinate
Vect1[2]:=Points[i+1,2]-Points[i,2]; //y-coordinate
length1:=sqrt(sqr(Vect1[1])+sqr(Vect1[2])); //length of Vect1

Vect2[1]:=Points[i-1,1]-Points[i,1]; //x-coordinate
Vect2[2]:=Points[i-1,2]-Points[i,2]; //y-coordinate
length2:=sqrt(sqr(Vect2[1])+sqr(Vect2[2])); // length of Vect2

Vect1[1]:=Vect1[1]/length1;//Norm Vect1
Vect1[2]:=Vect1[2]/length1;
Vect2[1]:=Vect2[1]/length2;//Norm Vect2
Vect2[2]:=Vect2[2]/length2;

ResultVect[1]:=Vect1[1]+Vect2[1]; // Compute bisector
ResultVect[2]:=Vect1[2]+Vect2[2];
ResultVectLength:=sqrt(sqr(ResultVect[1])+sqr(ResultVect[2]));

if (Vect1[1]*Vect2[2]-Vect1[2]*Vect2[1])<0 then IsObtuse:=true else IsObtuse:=false;
if IsObtuse then //if angle is obtuse then change result vector orientation
begin
ResultVect[1]:=-ResultVect[1];
ResultVect[2]:=-ResultVect[2];
end;

k:=StrToFloat(Edit1.Text); //
OutlinePoints[i,1]:=Points[i,1]+round(ResultVect[1]*k/ResultVectLength);
OutlinePoints[i,2]:=Points[i,2]+round(ResultVect[2]*k/ResultVectLength);

end;

k - длина, на которую нужно сместить результирующий контур

Points - массив с координатами точек исходного контура. Предполагается, что точки задаются по часовой стрелке.

OutlinePoints - массив с координатами нового контура.

Counter=N+1, где N - число точек начального контура, т.е. N+1-ая точка является одновременно и 1-ой. Это сделано для того, чтобы все координаты просчитывать в цикле.


 
Fenik   (2002-12-07 20:37) [21]

2 Alex45
>>А конкретнее? Для каких не работает?
Попробуй в моём примере задать побольше точек и поменять координаты...

Твой код не правильно работает. И вообще что за странное задание точек через массив [1..2]. Попробуй сам его проверить.
...Тут не только математика. Тут нужен энтузиазм программиста.


 
Alex45   (2002-12-09 06:41) [22]

2 Fenik.

Конкретно, пожалуйста, в каком случае работает неверно метод предложенный ZrenBy?

Массив точек задан в связи с тем, что TPoint(или его аналог) существует далеко не во всех ЯП :) Следовательно, человеку, не имеющему понятие об этом, сложно будет реализовать алгоритм.
А в общем, ты совершенно прав.

В том, что в здесь нужен энтузиазм - согласен. Но задача ЧИСТО математическая...

Жду здоровой критики.


 
Fenik   (2002-12-13 21:09) [23]

Задача:
Необходимо получит контур, находящийся внутри данного, на расстоянии k от каждой из сторон. (т.е надо получить пропорционально уменьшеный контур внутри данного).

Метод ZrenBy:
Выбираешь систему координат.
Берешь точку (x1,y1)
находишь два вектора из нее к соседним точкам
определяешь вектор-биссектрису к расчетной точке
находишь длину этого вектора, так чтобы расчетная точка
была на заданном удалении

Определяешь координаты расчетной точки.


Конечно, метод ZrenBy хорош (рациональнее метода Alex44), единичный вектор-биссектрису можно найти из суммы единичных вектров (между которыми биссектриса). Но из каждого угла по биссектрисе нельзя откладывать одно и то же расстояние, т.к. все углы могут быть разные и стороны нового многоугольника (если брать одно расстояние) окажутся не параллельными сторонам исходного. Первая проблема: какое откладывать расстояние по биссектрисе? Вторая проблема: в какую сторону откладывать? Если многоугольник выпуклый, то понятно где внутренняя часть, а если нет, то некоторые внутренние углы будут тупыми и получится так, что вектор-биссектриса будет направлен наружу. И, в конце концов, нужно определить имеет ли многоугольник самопересечения: если да, то или выйти из процедуры, или преобразовать массив точек в многоугольник без самопересечений.!?.


 
Alex45   (2002-12-15 07:41) [24]

Внутренность определяется по знаку векторного произведения. В моём коде стоит эта проверка. Условимся, что точки задаются ПО ЧАСОВОЙ стрелке и ВНУТРЕННЕЙ частью считаем то, что остаётся справа от контура при данном направлении обхода.
Насчёт того, что полученный контур не будет пропорционально уменьшенной копией заданного - согласен. Не додумал.
Предлагаю вариант, являющийся обобщением.
По заданным опорным точкам интерполируем (напр., кубическим сплайном), таким образом получая граничную кривую контура. Далее высчитываем нормаль в каждой точке получившейся кривой (уравнение кривой => касательная => нормаль), и, приводя её к нужной длине, на выходе имеем точки нового контура. Метод "в лоб". Вопрос о самопересечении - открыт.


 
msts   (2002-12-15 10:47) [25]

Ну че, решили задачу?
Если нет то по памяти могу сказать -
решается в два этапа:
1 найти центр многоугольника (не помню как называется)
В школе помнится был !учебник! по геометрии за !несколько! классов вот гдето в промежутке 70%-80% был раздел - как вписать заданный многоугольник в окружность, соот-но с формулами, по ним и находим эти координаты (центр окружности - центр многоугольника). Для любителей векторов переносим систему координат в этот центр.
2 перебираем все координаты многоугольника и смещаем их на указанную длину в направлении к центру (где то выше указано как)
и все вроде


 
Alex45   (2002-12-15 11:37) [26]

Просто класс!
Видимо у нас были разные школьные курсы по геометрии.
Здравый смысл - отдыхает. Попробуйте вписать ПРОИЗВОЛЬНЫЙ многоугольник в окружность. Интересно было бы взглянуть на Ваши формулы.
Вы, наверное, в курсе, что окружность определяется по 3 точкам единственным образом. Поясню: количество окружностей, которые можно получить по N точкам контура (3<=N<бескон-ть), равно, как Вы, безусловно, догадываетесь N. Какой из N центров Вы предпочитаете?
А если контур с самопересечениями? В результате - полный бардак.


 
zavdim   (2002-12-16 07:19) [27]


>
> Ssergy (07.11.02 18:32)
> Мастера, помогите пожалуйста.
> Есть замкнутый контур, заданный точкам.
> Необходимо получит контур, находящийся внутри данного, на
> расстоянии k от каждой из сторон. (т.е надо получить пропорционально
> уменьшеный контур внутри данного).
> Хоть какие - либо идеи please.
> Заранее спасибо.

Пропорционально уменьшенный и на одинаковом расстоянии - противоречие.
Возмите картину с рамкой определенной толщины - внутренность рамки не является подобной внешности. Вы уж определитесь чего надо.
Этот вопрос обсуждался на http://algolist.manual.ru/forum/viewtopic.php?t=33
я там Dmitriy.


 
zavdim   (2002-12-16 07:37) [28]

Если же просто ужать и всунуть. То в любой афинной системе координат делите координаты на что надо и потом делаете параллельный перенос. Вопрос о праллельном решите сами.
Но вот что вы при этом получите? Как например с 8-ой, или еще чего. В общем советую прочитать приведенную ссылку. Потом подумать, хотя обычно с этого начинают. Далее более четко оформить вопрос.



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2003.03.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.007 c
6-76554
neodiX
2003-01-30 15:56
2003.03.24
Subnet mask & broadcast


7-76687
BALU1111
2003-01-27 11:45
2003.03.24
Свекрнуть программу в System Tray


3-76261
dash78
2003-03-04 07:59
2003.03.24
Создание нового юзера


3-76360
Conder
2003-03-05 16:51
2003.03.24
Преобразование типа в SQL запросе...


1-76497
Random bystander
2003-03-11 12:41
2003.03.24
Проблема с динамическим созданием набора Shape-ов.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский