1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 /* Solaris 2.4, 2.6, probably 2.5.x, and possibly others prototype
31 finite() in ieeefp.h instead of math.h. finite() might not be
32 available at all on some HP-UX configurations (in which case,
33 you're on your own). */
38 #define isinf(a) (!finite(a))
42 /* #ifdef G_OS_WIN32 apparently _MSC_VER and mingw */
43 /* there are some things more in the gcc headers */
45 # define finite(a) _finite(a)
46 # define isnan(a) _isnan(a)
49 # define M_PI 3.14159265358979323846
50 # define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
51 # define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
54 /* gcc -std=c89 doesn't have it either */
59 #define M_SQRT2 G_SQRT2
62 #define M_SQRT1_2 (1.0/G_SQRT2)
66 Coordinate system used:
88 struct _IntRectangle
{
96 * BEZ_MOVE_TO: move to point p1
97 * BEZ_LINE_TO: line to point p1
98 * BEZ_CURVE_TO: curve to point p3 using p1 and p2 as control points.
101 enum {BEZ_MOVE_TO
, BEZ_LINE_TO
, BEZ_CURVE_TO
} type
;
106 #define ROUND(x) ((int) floor((x)+0.5))
108 /* inline these functions if the platform supports it */
110 G_INLINE_FUNC
void point_add(Point
*p1
, const Point
*p2
);
113 point_add(Point
*p1
, const Point
*p2
)
120 G_INLINE_FUNC
void point_sub(Point
*p1
, const Point
*p2
);
123 point_sub(Point
*p1
, const Point
*p2
)
130 G_INLINE_FUNC real
point_dot(const Point
*p1
, const Point
*p2
);
133 point_dot(const Point
*p1
, const Point
*p2
)
135 return p1
->x
*p2
->x
+ p1
->y
*p2
->y
;
139 G_INLINE_FUNC real
point_len(const Point
*p
);
142 point_len(const Point
*p
)
144 return sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
148 G_INLINE_FUNC
void point_scale(Point
*p
, real alpha
);
151 point_scale(Point
*p
, real alpha
)
158 G_INLINE_FUNC
void point_normalize(Point
*p
);
161 point_normalize(Point
*p
)
165 len
= sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
167 /* One could call it a bug to try normalizing a vector with
168 * len 0 and the result at least requires definition. But
169 * this is what makes the beziergon bounding box calculation
170 * work. What's the mathematical correct result of 0.0/0.0 ?
183 G_INLINE_FUNC
void point_rotate(Point
*p1
, const Point
*p2
);
186 point_rotate(Point
*p1
, const Point
*p2
)
188 p1
->x
= p1
->x
*p2
->x
- p1
->y
*p2
->y
;
189 p1
->y
= p1
->x
*p2
->y
+ p1
->y
*p2
->x
;
193 G_INLINE_FUNC
void point_get_normed(Point
*dst
, const Point
*src
);
196 point_get_normed(Point
*dst
, const Point
*src
)
200 len
= sqrt(src
->x
*src
->x
+ src
->y
*src
->y
);
202 dst
->x
= src
->x
/ len
;
203 dst
->y
= src
->y
/ len
;
207 G_INLINE_FUNC
void point_get_perp(Point
*dst
, const Point
*src
);
210 point_get_perp(Point
*dst
, const Point
*src
)
212 /* dst = the src vector, rotated 90deg counter clowkwise. src *must* be
213 normalized before. */
219 G_INLINE_FUNC
void point_copy(Point
*dst
, const Point
*src
);
222 point_copy(Point
*dst
, const Point
*src
)
224 /* Unfortunately, the compiler is not clever enough. And copying using
225 ints is faster if we don't computer based on the copied values, but
226 is slower if we have to make a FP reload afterwards.
227 point_copy() is meant for the latter case : then, the compiler is
228 able to shuffle and merge the FP loads. */
234 G_INLINE_FUNC
void point_add_scaled(Point
*dst
, const Point
*src
, real alpha
);
237 point_add_scaled(Point
*dst
, const Point
*src
, real alpha
)
239 /* especially useful if src is a normed vector... */
240 dst
->x
+= alpha
* src
->x
;
241 dst
->y
+= alpha
* src
->y
;
245 G_INLINE_FUNC
void point_copy_add_scaled(Point
*dst
, const Point
*src
,
250 point_copy_add_scaled(Point
*dst
, const Point
*src
,
251 const Point
*vct
, real alpha
)
253 /* especially useful if vct is a normed vector... */
254 dst
->x
= src
->x
+ (alpha
* vct
->x
);
255 dst
->y
= src
->y
+ (alpha
* vct
->y
);
259 void point_convex(Point
*dst
, const Point
*src1
, const Point
*src2
, real alpha
);
261 void rectangle_union(Rectangle
*r1
, const Rectangle
*r2
);
262 void int_rectangle_union(IntRectangle
*r1
, const IntRectangle
*r2
);
263 void rectangle_intersection(Rectangle
*r1
, const Rectangle
*r2
);
264 int rectangle_intersects(const Rectangle
*r1
, const Rectangle
*r2
);
265 int point_in_rectangle(const Rectangle
* r
, const Point
*p
);
266 int rectangle_in_rectangle(const Rectangle
* outer
, const Rectangle
*inner
);
267 void rectangle_add_point(Rectangle
*r
, const Point
*p
);
269 G_INLINE_FUNC gboolean
rectangle_equals(const Rectangle
*old_extents
,
270 const Rectangle
*new_extents
);
272 G_INLINE_FUNC gboolean
273 rectangle_equals(const Rectangle
*r1
, const Rectangle
*r2
)
275 return ( (r2
->left
== r1
->left
) &&
276 (r2
->right
== r1
->right
) &&
277 (r2
->top
== r1
->top
) &&
278 (r2
->bottom
== r1
->bottom
) );
282 G_INLINE_FUNC real
distance_point_point(const Point
*p1
, const Point
*p2
);
285 distance_point_point(const Point
*p1
, const Point
*p2
)
287 real dx
= p1
->x
- p2
->x
;
288 real dy
= p1
->y
- p2
->y
;
289 return sqrt(dx
*dx
+ dy
*dy
);
293 G_INLINE_FUNC
const Point
*closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
);
295 G_INLINE_FUNC
const Point
*
296 closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
)
298 if (distance_point_point(to
,p1
) < distance_point_point(to
,p2
))
304 G_INLINE_FUNC real
distance_point_point_manhattan(const Point
*p1
,
308 distance_point_point_manhattan(const Point
*p1
, const Point
*p2
)
310 real dx
= p1
->x
- p2
->x
;
311 real dy
= p1
->y
- p2
->y
;
312 return ABS(dx
) + ABS(dy
);
316 real
distance_rectangle_point(const Rectangle
*rect
, const Point
*point
);
317 real
distance_line_point(const Point
*line_start
, const Point
*line_end
,
318 real line_width
, const Point
*point
);
320 real
distance_polygon_point(const Point
*poly
, guint npoints
,
321 real line_width
, const Point
*point
);
323 /* bezier distance calculations */
324 real
distance_bez_seg_point(const Point
*b1
, const Point
*b2
,
325 const Point
*b3
, const Point
*b4
,
326 real line_width
, const Point
*point
);
327 real
distance_bez_line_point(const BezPoint
*b
, guint npoints
,
328 real line_width
, const Point
*point
);
329 real
distance_bez_shape_point(const BezPoint
*b
, guint npoints
,
330 real line_width
, const Point
*point
);
332 real
distance_ellipse_point(const Point
*centre
, real width
, real height
,
333 real line_width
, const Point
*point
);
335 typedef real Vector
[3];
336 typedef Vector Matrix
[3];
338 void transform_point (Matrix
, Point
*, Point
*);
339 void mult_matrix (Matrix
, Matrix
);
340 void identity_matrix (Matrix
);
341 void translate_matrix (Matrix
, real
, real
);
342 void scale_matrix (Matrix
, real
, real
);
343 void rotate_matrix (Matrix
, real
);
344 void xshear_matrix (Matrix
, real
);
345 void yshear_matrix (Matrix
, real
);
347 real
dot2(Point
*p1
, Point
*p2
);
348 void line_coef(real
*a
, real
*b
, real
*c
, Point
*p1
, Point
*p2
);
349 real
line_to_point(real a
, real b
, real c
, Point
*p
);
350 void point_perp(Point
*p
, real a
, real b
, real c
, Point
*perp
);
351 void fillet(Point
*p1
, Point
*p2
, Point
*p3
, Point
*p4
,
352 real r
, Point
*c
, real
*pa
, real
*aa
);
353 real
point_cross(Point
*p1
, Point
*p2
);
354 Point
calculate_object_edge(Point
*objmid
, Point
*end
, DiaObject
*obj
);
356 #endif /* GEOMETRY_H */