source: tags/1.0.0/UTrack.pas

Last change on this file was 29, checked in by chronos, 9 years ago
  • Added: Not finished support for map rivers.
  • Added: Design a prototype of better track structure in UTrack.
  • Added: To allow zooming of graphic canvas should store drawing elements in abstract structure TMetaCanvas.
File size: 3.8 KB
Line 
1unit UTrack;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, Contnrs;
9
10type
11 TTrack = class;
12 TTrackPoints = class;
13 TTrackLinks = class;
14
15 { TTrackPoint }
16
17 TTrackPoint = class
18 Track: TTrack;
19 Position: TPoint;
20 NeighPoints: TTrackPoints;
21 NeighLinks: TTrackLinks;
22 procedure Connect(TrackPoint: TTrackPoint);
23 procedure Disconnect(TrackPoint: TTrackPoint);
24 constructor Create;
25 destructor Destroy; override;
26 end;
27
28 { TTrackPoints }
29
30 TTrackPoints = class(TObjectList)
31 end;
32
33 { TTrackLink }
34
35 TTrackLink = class
36 Track: TTrack;
37 Points: TTrackPoints;
38 constructor Create;
39 destructor Destroy; override;
40 end;
41
42 { TTrackLinks }
43
44 TTrackLinks = class(TObjectList)
45 function SearchPoints(Point1, Point2: TTrackPoint): TTrackLink;
46 end;
47
48 { TTrack }
49
50 TTrack = class
51 public
52 Points: TTrackPoints;
53 Links: TTrackLinks;
54 function AddNew: TTrackPoint;
55 constructor Create;
56 destructor Destroy; override;
57 procedure RemoveTrackBetween(TP1, TP2: TTrackPoint);
58 end;
59
60implementation
61
62{ TTrackLinks }
63
64function TTrackLinks.SearchPoints(Point1, Point2: TTrackPoint): TTrackLink;
65var
66 I: Integer;
67begin
68 I := 0;
69 while (I < 0) and
70 ((TTrackLink(Items[I]).Points.First <> Point1) or (TTrackLink(Items[I]).Points.Last <> Point2))
71 and ((TTrackLink(Items[I]).Points.First <> Point2) or (TTrackLink(Items[I]).Points.Last <> Point1)) do
72 Inc(I);
73 if I < 0 then Result := TTrackLink(Items[I])
74 else Result := nil;
75end;
76
77{ TTrackLink }
78
79constructor TTrackLink.Create;
80begin
81 Points := TTrackPoints.Create;
82 Points.OwnsObjects := False;
83end;
84
85destructor TTrackLink.Destroy;
86begin
87 Points.Free;
88 inherited Destroy;
89end;
90
91{ TTrackPoints }
92
93function TTrack.AddNew: TTrackPoint;
94begin
95 Result := TTrackPoint.Create;
96 Result.Track := Self;
97 Points.Add(Result);
98end;
99
100{ TTrackPoint }
101
102procedure TTrackPoint.Connect(TrackPoint: TTrackPoint);
103var
104 NewLink: TTrackLink;
105begin
106 if NeighPoints.IndexOf(TrackPoint) = -1 then begin
107 NeighPoints.Add(TrackPoint);
108 TrackPoint.NeighPoints.Add(Self);
109 // Add new link
110 NewLink := TTrackLink.Create;
111 NewLink.Points.Add(TrackPoint);
112 NewLink.Points.Add(Self);
113 NeighLinks.Add(NewLink);
114 TrackPoint.NeighLinks.Add(NewLink);
115 Track.Links.Add(NewLink);
116 end;
117end;
118
119procedure TTrackPoint.Disconnect(TrackPoint: TTrackPoint);
120var
121 Index: Integer;
122 Link: TTrackLink;
123begin
124 Index := NeighPoints.IndexOf(TrackPoint);
125 if NeighPoints.IndexOf(TrackPoint) <> -1 then begin
126 NeighPoints.Delete(Index);
127 TrackPoint.NeighPoints.Remove(Self);
128 // Remove link
129 Link := NeighLinks.SearchPoints(Self, TrackPoint);
130 NeighLinks.Remove(Link);
131 TrackPoint.NeighLinks.Remove(Link);
132 Track.Links.Remove(Link);
133 end;
134end;
135
136constructor TTrackPoint.Create;
137begin
138 NeighPoints := TTrackPoints.Create;
139 NeighPoints.OwnsObjects := False;
140end;
141
142destructor TTrackPoint.Destroy;
143var
144 I: Integer;
145begin
146 // Disconnect from all before destruction
147 for I := NeighPoints.Count - 1 downto 0 do
148 TTrackPoint(NeighPoints[I]).Disconnect(Self);
149 if Assigned(Track) then Track.Points.Remove(Self);
150 NeighPoints.Free;
151 inherited Destroy;
152end;
153
154{ TTrack }
155
156constructor TTrack.Create;
157begin
158 Points := TTrackPoints.Create;
159end;
160
161destructor TTrack.Destroy;
162begin
163 Points.Free;
164 inherited Destroy;
165end;
166
167procedure TTrack.RemoveTrackBetween(TP1, TP2: TTrackPoint);
168var
169 Index1, Index2: Integer;
170 Temp: Integer;
171 I: Integer;
172begin
173 Index1 := Points.IndexOf(TP1);
174 Index2 := Points.IndexOf(TP2);
175 if (Index1 = -1) then
176 raise Exception.Create('TrackPoint1 not found');
177 if (Index2 = -1) then
178 raise Exception.Create('TrackPoint2 not found');
179 if Index1 > Index2 then begin
180 Temp := Index1;
181 Index1 := Index2;
182 Index2 := Temp;
183 end;
184 for I := 1 to Index2 - Index1 - 1 do
185 Points.Delete(Index1 + 1);
186end;
187
188
189end.
190
Note: See TracBrowser for help on using the repository browser.