Updated copyright text/header in most source files.
[geda-gaf.git] / libgeda / src / m_transform.c
blob96e8a4860a66759f678ff6f0b6c9b82ad6f0ccbf
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
20 #include <config.h>
21 #include <math.h>
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)
70 gdouble d;
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)
106 gint index;
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)
125 gdouble tx;
126 gdouble ty;
128 g_return_if_fail(transform!=NULL);
129 g_return_if_fail(x!=NULL);
130 g_return_if_fail(y!=NULL);
132 tx = *x;
133 ty = *y;
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)
146 gint index;
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;
165 gdouble c = cos(r);
166 gdouble s = sin(r);
167 TRANSFORM temp;
169 g_return_if_fail(transform!=NULL);
171 temp = *transform;
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;