2 /******************************************************************************
4 * DESCRIPTION: coordinate frames
5 * COPYRIGHT : (C) 2003 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
15 /******************************************************************************
17 ******************************************************************************/
19 struct scaling_rep
: public frame_rep
{
22 scaling_rep (double m
, point s
): magnify (m
), shift (s
) { linear
= true; }
24 return tuple ("scale", as_string (magnify
), as_tree (shift
)); }
25 point
direct_transform (point p
) { return shift
+ magnify
* p
; }
26 point
inverse_transform (point p
) { return (p
- shift
) / magnify
; }
27 point
jacobian (point p
, point v
, bool &error
) {
28 (void) p
; error
= false; return magnify
* v
; }
29 point
jacobian_of_inverse (point p
, point v
, bool &error
) {
30 (void) p
; error
= false; return v
/ magnify
; }
31 double direct_bound (point p
, double eps
) { (void) p
; return eps
/ magnify
; }
32 double inverse_bound (point p
, double eps
) { (void) p
; return eps
* magnify
; }
36 scaling (double magnify
, point shift
) {
37 return tm_new
<scaling_rep
> (magnify
, shift
);
40 /******************************************************************************
42 ******************************************************************************/
44 struct rotation_2D_rep
: public frame_rep
{
47 rotation_2D_rep (point o
, double a
): center (o
), angle (a
) { linear
= true; }
49 return tuple ("rotation_2D", as_tree (center
), as_string (angle
)); }
50 point
direct_transform (point p
) { return rotate_2D (p
, center
, angle
); }
51 point
inverse_transform (point p
) { return rotate_2D (p
, center
, -angle
); }
52 point
jacobian (point p
, point v
, bool &error
) {
53 (void) p
; error
= false; return rotate_2D (v
, point (0.0, 0.0), angle
); }
54 point
jacobian_of_inverse (point p
, point v
, bool &error
) {
55 (void) p
; error
= false; return rotate_2D (v
, point (0.0, 0.0), -angle
); }
56 double direct_bound (point p
, double eps
) { (void) p
; return eps
; }
57 double inverse_bound (point p
, double eps
) { (void) p
; return eps
; }
61 rotation_2D (point center
, double angle
) {
62 return tm_new
<rotation_2D_rep
> (center
, angle
);
65 /******************************************************************************
66 * Affine transformations
67 ******************************************************************************/
69 struct affine_2D_rep
: public frame_rep
{
71 affine_2D_rep (matrix
<double> m2
): m (m2
) {
74 // FIXME: Do we use "linear" in such a
75 // weakest sense for affine transforms ?
77 return tuple ("affine_2D", as_tree (m
)); }
78 point
direct_transform (point p
) {
79 point q
= point (3), r
;
80 q
[0]= p
[0]; q
[1]= p
[1]; q
[2]= 1.0;
82 return point (q
[0], q
[1]); }
83 point
inverse_transform (point p
) {
84 FAILED ("not yet implemented");
86 point
jacobian (point p
, point v
, bool &error
) {
87 (void) p
; error
= false; return j
* v
; }
88 point
jacobian_of_inverse (point p
, point v
, bool &error
) {
89 (void) p
; (void) v
; (void) error
;
90 FAILED ("not yet implemented");
92 double direct_bound (point p
, double eps
) { (void) p
; return eps
; }
93 double inverse_bound (point p
, double eps
) { (void) p
; return eps
; }
97 affine_2D (matrix
<double> m
) {
98 return tm_new
<affine_2D_rep
> (m
);
101 /******************************************************************************
103 ******************************************************************************/
105 struct compound_frame_rep
: public frame_rep
{
107 compound_frame_rep (frame f1b
, frame f2b
):
108 f1 (f1b
), f2 (f2b
) { linear
= f1
->linear
&& f2
->linear
; }
109 operator tree () { return tuple ("compound", (tree
) f1
, (tree
) f2
); }
110 point
direct_transform (point p
) { return f1 (f2 (p
)); }
111 point
inverse_transform (point p
) { return f2
[f1
[p
]]; }
112 point
jacobian (point p
, point v
, bool &error
) {
114 point w2
= f2
->jacobian (p
, v
, error2
);
115 point w1
= f1
->jacobian (f2 (p
), w2
, error
);
119 point
jacobian_of_inverse (point p
, point v
, bool &error
) {
120 (void) p
; (void) v
; (void) error
;
121 FAILED ("not yet implemented");
124 double direct_bound (point p
, double eps
) {
125 return f1
->direct_bound (f2(p
), f2
->direct_bound (p
, eps
)); }
126 double inverse_bound (point p
, double eps
) {
127 return f2
->inverse_bound (f1
[p
], f1
->inverse_bound (p
, eps
)); }
131 operator * (frame f1
, frame f2
) {
132 return tm_new
<compound_frame_rep
> (f1
, f2
);
135 /******************************************************************************
137 ******************************************************************************/
139 struct inverted_frame_rep
: public frame_rep
{
141 inverted_frame_rep (frame f2
): f (f2
) { linear
= f
->linear
; }
142 operator tree () { return tuple ("inverse", (tree
) f
); }
143 point
direct_transform (point p
) { return f
[p
]; }
144 point
inverse_transform (point p
) { return f (p
); }
145 point
jacobian (point p
, point v
, bool &error
) {
146 return f
->jacobian_of_inverse (p
, v
, error
); }
147 point
jacobian_of_inverse (point p
, point v
, bool &error
) {
148 return f
->jacobian (p
, v
, error
); }
149 double direct_bound (point p
, double eps
) {
150 return f
->inverse_bound (p
, eps
); }
151 double inverse_bound (point p
, double eps
) {
152 return f
->direct_bound (p
, eps
); }
157 return tm_new
<inverted_frame_rep
> (f
);