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.
19 /** \file geometry.h -- basic geometry classes and functions operationg on them */
32 /* Solaris 2.4, 2.6, probably 2.5.x, and possibly others prototype
33 finite() in ieeefp.h instead of math.h. finite() might not be
34 available at all on some HP-UX configurations (in which case,
35 you're on your own). */
40 #define isinf(a) (!finite(a))
44 /* #ifdef G_OS_WIN32 apparently _MSC_VER and mingw */
45 /* there are some things more in the gcc headers */
47 # define finite(a) _finite(a)
48 # define isnan(a) _isnan(a)
51 # define M_PI 3.14159265358979323846
52 # define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
53 # define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
56 /* gcc -std=c89 doesn't have it either */
61 #define M_SQRT2 G_SQRT2
64 #define M_SQRT1_2 (1.0/G_SQRT2)
68 Coordinate system used:
78 /*! \brief A two dimensional position */
80 coord x
; /*!< horizontal */
81 coord y
; /*!< vertical */
84 /*! \brief A rectangle given by upper left and lower right corner */
87 coord left
; /*!< x1 */
88 coord bottom
; /*!< y2 */
89 coord right
; /*!< x2 */
92 /*! \brief A rectangle for fixed point e.g. pixel coordinates */
93 struct _IntRectangle
{
96 int bottom
; /*!< y2 */
101 * \brief BezPoint is a bezier point forming _Bezierline or _Beziergon
105 BEZ_MOVE_TO
, /*!< move to point p1 */
106 BEZ_LINE_TO
, /*!< line to point p1 */
107 BEZ_CURVE_TO
/*!< curve to point p3 using p1 and p2 as control points */
109 Point p1
; /*!< main point in case of move or line-to, otherwise first control point */
110 Point p2
; /*!< second control point */
111 Point p3
; /*!< main point for 'true' bezier point */
115 #define ROUND(x) ((int) floor((x)+0.5))
117 /* inline these functions if the platform supports it */
119 G_INLINE_FUNC
void point_add(Point
*p1
, const Point
*p2
);
122 point_add(Point
*p1
, const Point
*p2
)
129 G_INLINE_FUNC
void point_sub(Point
*p1
, const Point
*p2
);
132 point_sub(Point
*p1
, const Point
*p2
)
139 G_INLINE_FUNC real
point_dot(const Point
*p1
, const Point
*p2
);
142 point_dot(const Point
*p1
, const Point
*p2
)
144 return p1
->x
*p2
->x
+ p1
->y
*p2
->y
;
148 G_INLINE_FUNC real
point_len(const Point
*p
);
151 point_len(const Point
*p
)
153 return sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
157 G_INLINE_FUNC
void point_scale(Point
*p
, real alpha
);
160 point_scale(Point
*p
, real alpha
)
167 G_INLINE_FUNC
void point_normalize(Point
*p
);
170 point_normalize(Point
*p
)
174 len
= sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
176 /* One could call it a bug to try normalizing a vector with
177 * len 0 and the result at least requires definition. But
178 * this is what makes the beziergon bounding box calculation
179 * work. What's the mathematical correct result of 0.0/0.0 ?
192 G_INLINE_FUNC
void point_rotate(Point
*p1
, const Point
*p2
);
195 point_rotate(Point
*p1
, const Point
*p2
)
197 p1
->x
= p1
->x
*p2
->x
- p1
->y
*p2
->y
;
198 p1
->y
= p1
->x
*p2
->y
+ p1
->y
*p2
->x
;
202 G_INLINE_FUNC
void point_get_normed(Point
*dst
, const Point
*src
);
205 point_get_normed(Point
*dst
, const Point
*src
)
209 len
= sqrt(src
->x
*src
->x
+ src
->y
*src
->y
);
211 dst
->x
= src
->x
/ len
;
212 dst
->y
= src
->y
/ len
;
216 G_INLINE_FUNC
void point_get_perp(Point
*dst
, const Point
*src
);
219 point_get_perp(Point
*dst
, const Point
*src
)
221 /* dst = the src vector, rotated 90deg counter clowkwise. src *must* be
222 normalized before. */
228 G_INLINE_FUNC
void point_copy(Point
*dst
, const Point
*src
);
231 point_copy(Point
*dst
, const Point
*src
)
233 /* Unfortunately, the compiler is not clever enough. And copying using
234 ints is faster if we don't computer based on the copied values, but
235 is slower if we have to make a FP reload afterwards.
236 point_copy() is meant for the latter case : then, the compiler is
237 able to shuffle and merge the FP loads. */
243 G_INLINE_FUNC
void point_add_scaled(Point
*dst
, const Point
*src
, real alpha
);
246 point_add_scaled(Point
*dst
, const Point
*src
, real alpha
)
248 /* especially useful if src is a normed vector... */
249 dst
->x
+= alpha
* src
->x
;
250 dst
->y
+= alpha
* src
->y
;
254 G_INLINE_FUNC
void point_copy_add_scaled(Point
*dst
, const Point
*src
,
259 point_copy_add_scaled(Point
*dst
, const Point
*src
,
260 const Point
*vct
, real alpha
)
262 /* especially useful if vct is a normed vector... */
263 dst
->x
= src
->x
+ (alpha
* vct
->x
);
264 dst
->y
= src
->y
+ (alpha
* vct
->y
);
268 void point_convex(Point
*dst
, const Point
*src1
, const Point
*src2
, real alpha
);
270 void rectangle_union(Rectangle
*r1
, const Rectangle
*r2
);
271 void int_rectangle_union(IntRectangle
*r1
, const IntRectangle
*r2
);
272 void rectangle_intersection(Rectangle
*r1
, const Rectangle
*r2
);
273 int rectangle_intersects(const Rectangle
*r1
, const Rectangle
*r2
);
274 int point_in_rectangle(const Rectangle
* r
, const Point
*p
);
275 int rectangle_in_rectangle(const Rectangle
* outer
, const Rectangle
*inner
);
276 void rectangle_add_point(Rectangle
*r
, const Point
*p
);
278 G_INLINE_FUNC gboolean
rectangle_equals(const Rectangle
*old_extents
,
279 const Rectangle
*new_extents
);
281 G_INLINE_FUNC gboolean
282 rectangle_equals(const Rectangle
*r1
, const Rectangle
*r2
)
284 return ( (r2
->left
== r1
->left
) &&
285 (r2
->right
== r1
->right
) &&
286 (r2
->top
== r1
->top
) &&
287 (r2
->bottom
== r1
->bottom
) );
291 G_INLINE_FUNC real
distance_point_point(const Point
*p1
, const Point
*p2
);
294 distance_point_point(const Point
*p1
, const Point
*p2
)
296 real dx
= p1
->x
- p2
->x
;
297 real dy
= p1
->y
- p2
->y
;
298 return sqrt(dx
*dx
+ dy
*dy
);
302 G_INLINE_FUNC
const Point
*closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
);
304 G_INLINE_FUNC
const Point
*
305 closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
)
307 if (distance_point_point(to
,p1
) < distance_point_point(to
,p2
))
313 G_INLINE_FUNC real
distance_point_point_manhattan(const Point
*p1
,
317 distance_point_point_manhattan(const Point
*p1
, const Point
*p2
)
319 real dx
= p1
->x
- p2
->x
;
320 real dy
= p1
->y
- p2
->y
;
321 return ABS(dx
) + ABS(dy
);
325 real
distance_rectangle_point(const Rectangle
*rect
, const Point
*point
);
326 real
distance_line_point(const Point
*line_start
, const Point
*line_end
,
327 real line_width
, const Point
*point
);
329 real
distance_polygon_point(const Point
*poly
, guint npoints
,
330 real line_width
, const Point
*point
);
332 /* bezier distance calculations */
333 real
distance_bez_seg_point(const Point
*b1
, const Point
*b2
,
334 const Point
*b3
, const Point
*b4
,
335 real line_width
, const Point
*point
);
336 real
distance_bez_line_point(const BezPoint
*b
, guint npoints
,
337 real line_width
, const Point
*point
);
338 real
distance_bez_shape_point(const BezPoint
*b
, guint npoints
,
339 real line_width
, const Point
*point
);
341 real
distance_ellipse_point(const Point
*centre
, real width
, real height
,
342 real line_width
, const Point
*point
);
344 typedef real Vector
[3];
345 typedef Vector Matrix
[3];
347 void transform_point (Matrix
, Point
*, Point
*);
348 void mult_matrix (Matrix
, Matrix
);
349 void identity_matrix (Matrix
);
350 void translate_matrix (Matrix
, real
, real
);
351 void scale_matrix (Matrix
, real
, real
);
352 void rotate_matrix (Matrix
, real
);
353 void xshear_matrix (Matrix
, real
);
354 void yshear_matrix (Matrix
, real
);
356 real
dot2(Point
*p1
, Point
*p2
);
357 void line_coef(real
*a
, real
*b
, real
*c
, Point
*p1
, Point
*p2
);
358 real
line_to_point(real a
, real b
, real c
, Point
*p
);
359 void point_perp(Point
*p
, real a
, real b
, real c
, Point
*perp
);
360 void fillet(Point
*p1
, Point
*p2
, Point
*p3
, Point
*p4
,
361 real r
, Point
*c
, real
*pa
, real
*aa
);
362 real
point_cross(Point
*p1
, Point
*p2
);
363 Point
calculate_object_edge(Point
*objmid
, Point
*end
, DiaObject
*obj
);
365 #endif /* GEOMETRY_H */