1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
22 #include <libgeda_priv.h>
24 /*! \brief Combines two transformations
26 * Combines two matricies using matrix multiplication: a*b.
28 * \param result [out] The resulting transformation. If either operand is
29 * NULL, the contents of the result remain unaltered.
30 * \param a [in] The second operand.
31 * \param b [in] The second operand.
33 void m_transform_combine(TRANSFORM
*result
, TRANSFORM
*a
, TRANSFORM
*b
)
35 g_return_if_fail(result
!=NULL
);
36 g_return_if_fail(a
!=NULL
);
37 g_return_if_fail(b
!=NULL
);
39 result
->m
[0][0] = a
->m
[0][0] * b
->m
[0][0] + a
->m
[0][1] * b
->m
[1][0];
40 result
->m
[0][1] = a
->m
[0][0] * b
->m
[0][1] + a
->m
[0][1] * b
->m
[1][1];
41 result
->m
[0][2] = a
->m
[0][0] * b
->m
[0][2] + a
->m
[0][1] * b
->m
[1][2] + a
->m
[0][2];
42 result
->m
[1][0] = a
->m
[1][0] * b
->m
[0][0] + a
->m
[1][1] * b
->m
[1][0];
43 result
->m
[1][1] = a
->m
[1][0] * b
->m
[0][1] + a
->m
[1][1] * b
->m
[1][1];
44 result
->m
[1][2] = a
->m
[1][0] * b
->m
[0][2] + a
->m
[1][1] * b
->m
[1][2] + a
->m
[1][2];
47 /*! \brief Initialize a transform with the identity matrix.
49 * \param transform [out] The transform to initialize with the identity matrix.
51 void m_transform_init(TRANSFORM
*transform
)
53 g_return_if_fail(transform
!=NULL
);
55 transform
->m
[0][0] = 1;
56 transform
->m
[0][1] = 0;
57 transform
->m
[0][2] = 0;
58 transform
->m
[1][0] = 0;
59 transform
->m
[1][1] = 1;
60 transform
->m
[1][2] = 0;
63 /*! \brief Calculates the inverse transform
65 * \param transform [in] The given matrix
66 * \param inverse [out] The inverse of the given matrix.
68 void m_transform_invert(TRANSFORM
*transform
, TRANSFORM
*inverse
)
72 g_return_if_fail(transform
!=NULL
);
73 g_return_if_fail(inverse
!=NULL
);
75 d
= transform
->m
[0][0]*transform
->m
[1][1] - transform
->m
[1][0]*transform
->m
[0][1];
77 inverse
->m
[0][0] = transform
->m
[1][1] / d
;
78 inverse
->m
[0][1] = -transform
->m
[0][1] / d
;
79 inverse
->m
[0][2] = ( transform
->m
[0][1]*transform
->m
[1][2] - transform
->m
[1][1]*transform
->m
[0][2] ) / d
;
80 inverse
->m
[1][0] = -transform
->m
[1][0] / d
;
81 inverse
->m
[1][1] = transform
->m
[0][0] / d
;
82 inverse
->m
[1][2] = -( transform
->m
[0][0]*transform
->m
[1][2] - transform
->m
[1][0]*transform
->m
[0][2] ) / d
;
85 /*! \brief Transforms a line segment
87 * \param transform [in] The transform function.
88 * \param line [inout] The line to transform.
90 void m_transform_line(TRANSFORM
*transform
, LINE
*line
)
92 g_return_if_fail(transform
!=NULL
);
93 g_return_if_fail(line
!=NULL
);
95 m_transform_point(transform
, &(line
->x
[0]), &(line
->y
[0]));
96 m_transform_point(transform
, &(line
->x
[1]), &(line
->y
[1]));
99 /*! \brief Transforms multiple line segments
101 * \param transform [in] The transform function.
102 * \param lines [inout] The GArray of LINE to transform.
104 void m_transform_lines(TRANSFORM
*transform
, GArray
*lines
)
108 g_return_if_fail(transform
!=NULL
);
109 g_return_if_fail(lines
!=NULL
);
111 for (index
=0; index
<lines
->len
; index
++) {
112 LINE
*line
= &g_array_index(lines
, LINE
, index
);
113 m_transform_line(transform
, line
);
117 /*! \brief Transforms a point
119 * \param x [inout] The x coordinate to transform.
120 * \param y [inout] The y coordinate to transform.
121 * \param transform [in] The transform function.
123 void m_transform_point(TRANSFORM
*transform
, gint
*x
, gint
*y
)
128 g_return_if_fail(transform
!=NULL
);
129 g_return_if_fail(x
!=NULL
);
130 g_return_if_fail(y
!=NULL
);
135 *x
= round(transform
->m
[0][0] * tx
+ transform
->m
[0][1] * ty
+ transform
->m
[0][2]);
136 *y
= round(transform
->m
[1][0] * tx
+ transform
->m
[1][1] * ty
+ transform
->m
[1][2]);
139 /*! \brief Transforms a polyline or polygon
141 * \param transform [in] The transform function.
142 * \param points [inout] The GArray of sPOINT to transform.
144 void m_transform_points(TRANSFORM
*transform
, GArray
*points
)
148 g_return_if_fail(transform
!=NULL
);
149 g_return_if_fail(points
!=NULL
);
151 for (index
=0; index
<points
->len
; index
++) {
152 sPOINT
*point
= &g_array_index(points
, sPOINT
, index
);
153 m_transform_point(transform
, &(point
->x
), &(point
->y
));
157 /*! \brief Adds a rotation to the transformation
159 * \param transform [inout] The given matrix
160 * \param angle [in] The angle to rotate
162 void m_transform_rotate(TRANSFORM
*transform
, gdouble angle
)
164 gdouble r
= G_PI
*angle
/180.0;
169 g_return_if_fail(transform
!=NULL
);
173 transform
->m
[0][0] = temp
.m
[0][0] * c
+ temp
.m
[0][1] * s
;
174 transform
->m
[0][1] = temp
.m
[0][0] * -s
+ temp
.m
[0][1] * c
;
175 transform
->m
[1][0] = temp
.m
[1][0] * c
+ temp
.m
[1][1] * s
;
176 transform
->m
[1][1] = temp
.m
[1][0] * -s
+ temp
.m
[1][1] * c
;
179 /*! \brief Adds a scaling to the transformation
181 * \param transform [inout] The given matrix
182 * \param factor [in] The amount to scale the transform. This parameter must
183 * not be zero, or the matrix becomes singular.
185 void m_transform_scale(TRANSFORM
*transform
, gdouble factor
)
187 g_return_if_fail(transform
!=NULL
);
188 g_return_if_fail(factor
!=0);
190 transform
->m
[0][0] *= factor
;
191 transform
->m
[0][1] *= factor
;
192 transform
->m
[1][0] *= factor
;
193 transform
->m
[1][1] *= factor
;
196 /*! \brief Adds a translation to the transformation
198 * \param transform [inout] The given matrix.
199 * \param dx [in] The amount to translate on the x axis.
200 * \param dy [in] The amount to translate on the y axis.
202 void m_transform_translate(TRANSFORM
*transform
, gdouble dx
, gdouble dy
)
204 g_return_if_fail(transform
!=NULL
);
206 transform
->m
[0][2] += dx
;
207 transform
->m
[1][2] += dy
;