1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
17 #include "agg_trans_double_path.h"
22 //------------------------------------------------------------------------
23 trans_double_path::trans_double_path() :
30 m_preserve_x_scale(true)
35 //------------------------------------------------------------------------
36 void trans_double_path::reset()
38 m_src_vertices1
.remove_all();
39 m_src_vertices2
.remove_all();
47 //------------------------------------------------------------------------
48 void trans_double_path::move_to1(double x
, double y
)
50 if(m_status1
== initial
)
52 m_src_vertices1
.modify_last(vertex_dist(x
, y
));
53 m_status1
= making_path
;
62 //------------------------------------------------------------------------
63 void trans_double_path::line_to1(double x
, double y
)
65 if(m_status1
== making_path
)
67 m_src_vertices1
.add(vertex_dist(x
, y
));
72 //------------------------------------------------------------------------
73 void trans_double_path::move_to2(double x
, double y
)
75 if(m_status2
== initial
)
77 m_src_vertices2
.modify_last(vertex_dist(x
, y
));
78 m_status2
= making_path
;
87 //------------------------------------------------------------------------
88 void trans_double_path::line_to2(double x
, double y
)
90 if(m_status2
== making_path
)
92 m_src_vertices2
.add(vertex_dist(x
, y
));
97 //------------------------------------------------------------------------
98 double trans_double_path::finalize_path(vertex_storage
& vertices
)
104 if(vertices
.size() > 2)
106 if(vertices
[vertices
.size() - 2].dist
* 10.0 <
107 vertices
[vertices
.size() - 3].dist
)
109 d
= vertices
[vertices
.size() - 3].dist
+
110 vertices
[vertices
.size() - 2].dist
;
112 vertices
[vertices
.size() - 2] =
113 vertices
[vertices
.size() - 1];
115 vertices
.remove_last();
116 vertices
[vertices
.size() - 2].dist
= d
;
121 vertices
.close(false);
122 for(i
= 0; i
< vertices
.size(); i
++)
124 vertex_dist
& v
= vertices
[i
];
130 return (vertices
.size() - 1) / dist
;
134 //------------------------------------------------------------------------
135 void trans_double_path::finalize_paths()
137 if(m_status1
== making_path
&& m_src_vertices1
.size() > 1 &&
138 m_status2
== making_path
&& m_src_vertices2
.size() > 1)
140 m_kindex1
= finalize_path(m_src_vertices1
);
141 m_kindex2
= finalize_path(m_src_vertices2
);
148 //------------------------------------------------------------------------
149 double trans_double_path::total_length1() const
151 if(m_base_length
>= 1e-10) return m_base_length
;
152 return (m_status1
== ready
) ?
153 m_src_vertices1
[m_src_vertices1
.size() - 1].dist
:
158 //------------------------------------------------------------------------
159 double trans_double_path::total_length2() const
161 if(m_base_length
>= 1e-10) return m_base_length
;
162 return (m_status2
== ready
) ?
163 m_src_vertices2
[m_src_vertices2
.size() - 1].dist
:
168 //------------------------------------------------------------------------
169 void trans_double_path::transform1(const vertex_storage
& vertices
,
170 double kindex
, double kx
,
171 double *x
, double* y
) const
182 // Extrapolation on the left
183 //--------------------------
186 dx
= vertices
[1].x
- x1
;
187 dy
= vertices
[1].y
- y1
;
188 dd
= vertices
[1].dist
- vertices
[0].dist
;
192 if(*x
> vertices
[vertices
.size() - 1].dist
)
194 // Extrapolation on the right
195 //--------------------------
196 unsigned i
= vertices
.size() - 2;
197 unsigned j
= vertices
.size() - 1;
200 dx
= x1
- vertices
[i
].x
;
201 dy
= y1
- vertices
[i
].y
;
202 dd
= vertices
[j
].dist
- vertices
[i
].dist
;
203 d
= *x
- vertices
[j
].dist
;
208 //--------------------------
210 unsigned j
= vertices
.size() - 1;
211 if(m_preserve_x_scale
)
214 for(i
= 0; (j
- i
) > 1; )
216 if(*x
< vertices
[k
= (i
+ j
) >> 1].dist
)
225 d
= vertices
[i
].dist
;
226 dd
= vertices
[j
].dist
- d
;
231 i
= (unsigned)floor(*x
* kindex
);
233 dd
= vertices
[j
].dist
- vertices
[i
].dist
;
234 d
= ((*x
* kindex
) - i
) * dd
;
238 dx
= vertices
[j
].x
- x1
;
239 dy
= vertices
[j
].y
- y1
;
241 *x
= x1
+ dx
* d
/ dd
;
242 *y
= y1
+ dy
* d
/ dd
;
246 //------------------------------------------------------------------------
247 void trans_double_path::transform(double *x
, double *y
) const
249 if(m_status1
== ready
&& m_status2
== ready
)
251 if(m_base_length
> 1e-10)
253 *x
*= m_src_vertices1
[m_src_vertices1
.size() - 1].dist
/
261 double dd
= m_src_vertices2
[m_src_vertices2
.size() - 1].dist
/
262 m_src_vertices1
[m_src_vertices1
.size() - 1].dist
;
264 transform1(m_src_vertices1
, m_kindex1
, 1.0, &x1
, &y1
);
265 transform1(m_src_vertices2
, m_kindex2
, dd
, &x2
, &y2
);
267 *x
= x1
+ *y
* (x2
- x1
) / m_base_height
;
268 *y
= y1
+ *y
* (y2
- y1
) / m_base_height
;