1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4 (Public License)
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6 // Pascal Port By: Milan Marusinec alias Milano
7 //                 milan@marusinec.sk
8 //                 http://www.aggpas.org
9 // Copyright (c) 2005-2006
10 //
11 // Permission to copy, use, modify, sell and distribute this software
12 // is granted provided this copyright notice appears in all copies.
13 // This software is provided "as is" without express or implied
14 // warranty, and with no claim as to its suitability for any purpose.
15 //
16 //----------------------------------------------------------------------------
17 // Contact: mcseem@antigrain.com
18 //          mcseemagg@yahoo.com
19 //          http://www.antigrain.com
20 //
21 //----------------------------------------------------------------------------
22 //
23 // vertex_sequence container and vertex_dist struct
24 //
25 // [Pascal Port History] -----------------------------------------------------
26 //
27 // 19.12.2005-Milano: Unit port establishment
28 //
29 { agg_vertex_sequence.pas }
30 unit
31  agg_vertex_sequence ;
32 
33 INTERFACE
34 
35 {$I agg_mode.inc }
36 
37 uses
38  agg_basics ,
39  agg_array ;
40 
41 { TYPES DEFINITION }
42 type
hisnull43  func_vertex_sequence = function(this ,val : pointer ) : boolean;
44 
45 //----------------------------------------------------------vertex_sequence
46 // Modified agg::pod_deque. The data is interpreted as a sequence of vertices.
47  vertex_sequence_ptr = ^vertex_sequence;
48  vertex_sequence = object(pod_deque )
49    func_operator_vertex_sequence : func_vertex_sequence;
50 
51    constructor Construct(entry_sz : unsigned; s_ : unsigned = 6; fovs : func_vertex_sequence = NIL );
52 
53    procedure add(val : pointer );
54 
55    procedure modify_last(val : pointer);
56 
57    procedure close(remove_flag : boolean );
58 
59   end;
60 
61 // Coinciding points maximal distance (Epsilon)
62 const
63  vertex_dist_epsilon : double = 1e-14;
64 
65 //-------------------------------------------------------------vertex_dist
66 // Vertex (x, y) with the distance to the next one. The last vertex has
67 // distance between the last and the first points if the polygon is closed
68 // and 0.0 if it's a polyline.
69 type
70  vertex_dist_ptr = ^vertex_dist;
71  vertex_dist = record
72    x ,y ,dist : double;
73 
74   end;
75 
76  vertex_dist_cmd_ptr = ^vertex_dist_cmd;
77  vertex_dist_cmd = record
78    x ,y ,dist : double;
79 
80    cmd : unsigned;
81 
82   end;
83 
84 { GLOBAL PROCEDURES }
85  function  vertex_dist_func_operator(this ,val : vertex_dist_ptr ) : boolean;
86 
87 
88 IMPLEMENTATION
89 { LOCAL VARIABLES & CONSTANTS }
90 uses
91  agg_math ;
92 
93 { UNIT IMPLEMENTATION }
94 { FUNC_OPERATOR_VERTEX_DIST }
95 function vertex_dist_func_operator;
96 var
97  ret : boolean;
98 
99 begin
100  this.dist:=calc_distance(this.x ,this.y ,val.x ,val.y );
101 
102  ret:=this.dist > vertex_dist_epsilon;
103 
104  if not ret then
105   this.dist:=1 / vertex_dist_epsilon;
106 
107  result:=ret;
108 
109 end;
110 
111 { CONSTRUCT }
112 constructor vertex_sequence.Construct;
113 begin
114  inherited Construct(entry_sz ,s_ );
115 
116  if @fovs = NIL then
117   func_operator_vertex_sequence:=@vertex_dist_func_operator
118  else
119   func_operator_vertex_sequence:=fovs;
120 
121 end;
122 
123 { ADD }
124 procedure vertex_sequence.add;
125 begin
126  if size > 1 then
127   if not func_operator_vertex_sequence(
128           array_operator(size - 2 ) ,
129           array_operator(size - 1 ) ) then
130    remove_last;
131 
132  inherited add(val );
133 
134 end;
135 
136 { MODIFY_LAST }
137 procedure vertex_sequence.modify_last;
138 begin
139  remove_last;
140 
141  add(val );
142 
143 end;
144 
145 { CLOSE }
146 procedure vertex_sequence.close;
147 var
148  t : pointer;
149 
150 begin
151  while size > 1 do
152   begin
153    if func_operator_vertex_sequence(
154        array_operator(size - 2 ) ,
155        array_operator(size - 1 ) ) then
156     break;
157 
158    t:=array_operator(size - 1 );
159 
160    remove_last;
161    modify_last(t );
162 
163   end;
164 
165  if remove_flag then
166   while size > 1 do
167    begin
168     if func_operator_vertex_sequence(
169         array_operator(size - 1 ) ,
170         array_operator(0 ) ) then
171      break;
172 
173     remove_last;
174 
175    end;
176 
177 end;
178 
179 END.
180 
181