// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) unit DMCollect; {$reference 'System.Drawing.dll'} interface uses System.Drawing, System.Collections; type Vector = Point; Cell = record p: Point; v: Vector; procedure Init(x1,y1,x2,y2: integer); procedure InitAB(a,b: Point); function ToString: string; override; begin Result := IntToStr(p.x)+','+IntToStr(p.y)+','+IntToStr(v.x)+','+IntToStr(v.y); end; end; SortedCollection = class private a: ArrayList; function GetCount: integer; begin Result := a.Count; end; function GetItem(i: integer): Cell; begin Result := Cell(a[i]); //!! Не будет работать для Item[i].a.x := 1; !!!!!!! end; procedure SetItem(i: integer; c: Cell); begin a[i] := c; end; public property Count: integer read GetCount; property Items[i: integer]: Cell read GetItem write SetItem; default; constructor Create; destructor Done; procedure Insert (x1,y1,x2,y2: integer); procedure InsertAB (A,B: Point); procedure Print; procedure Normalize; procedure Clear; function IsEmpty: boolean; end; function InitVector(a,b: Point): Vector; function Len2(v: Vector): longint; function IsBetweenPP (P,A,B: Point): boolean; function IsEqualPP (P1,P2: Point): boolean; function IsEqualPxy (P: Point; x,y: integer): boolean; function LessThenPP (P1,P2: Point): boolean; function LessThenPxy (P: Point; x,y: integer): boolean; function LessThenVV (A,B: Vector): boolean; function IsParallel (A,B: Vector): boolean; function IsEqualCC (C1,C2: Cell): boolean; function LessThenCC (C1,C2: Cell): boolean; function LessEqualCC (C1,C2: Cell): boolean; function IsEqualSC(SC1,SC2: SortedCollection): boolean; {--------------------------------------------} implementation {--------------------------------------------} function IsEqualPP (P1,P2: Point): boolean; begin IsEqualPP := (P1.x=P2.x) and (P1.y=P2.y) end; function IsEqualPxy (P: Point; x,y: integer): boolean; begin IsEqualPxy := (x=P.x) and (y=P.y) end; function LessThenPP (P1,P2: Point): boolean; begin LessThenPP := (P1.x 0 end; function LessEqualVV (A,B: Vector): boolean; begin LessEqualVV := longint(A.x)*longint(B.y) - longint(A.y)*longint(B.x) >= 0 end; function IsParallel (A,B: Vector): boolean; begin IsParallel := longint(A.x)*longint(B.y) = longint(A.y)*longint(B.x) end; function IsEqualCC (C1,C2: Cell): boolean; begin IsEqualCC := isequalPP(C1.p,C2.p) and isequalPP(C1.v,C2.v) end; function LessThenCC (C1,C2: Cell): boolean; var vv: vector; ip: boolean; {Самое сложное условие} begin vv := initVector(C1.p,C2.p); ip := IsParallel(C1.v,C2.v); {C1nil do begin H1 := H^.next; k := 0; if IsParallel(H^.v,H1^.v) then begin pend.init(H^.p.x+H^.v.x,H^.p.y+H^.v.y); p1end.init(H1^.p.x+H1^.v.x,H1^.p.y+H1^.v.y); if IsBetweenPP(H1^.p,H^.p,Pend) {если P1 между P и P+v} or IsBetweenPP(H^.p,H1^.p,P1end) {если P между P1 и P1+v} then begin {найти начало и конец нового вектора} if LessThenPP(H^.p,H1^.p) then pnew:=H^.p else pnew:=H1^.p; if LessThenPP(pend,p1end) then pnewend:=p1end else pnewend:=pend; { Слить } H^.p.init(pnew.x,pnew.y); H^.v.InitVector(pnew,pnewend); H^.next := H1^.next; dispose(H1); b:=True; k := 1; {А если v1 целиком внутри v ???} {По моему, тогда на следующем проходе и для этого k} end; end; if k=0 then H := H^.next; end; if b then goto 1; {поскольку не все могли слиться} {не лучший алгоритм, но...}*) end; procedure SortedCollection.Clear; begin a.Clear; end; destructor SortedCollection.Done; begin Clear; end; function SortedCollection.IsEmpty: boolean; begin Result := a.Count = 0; end; end.