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)
70 Coordinate system used:
80 /*! \brief A two dimensional position */
82 coord x
; /*!< horizontal */
83 coord y
; /*!< vertical */
86 /*! \brief A rectangle given by upper left and lower right corner */
89 coord left
; /*!< x1 */
90 coord bottom
; /*!< y2 */
91 coord right
; /*!< x2 */
94 /*! \brief A rectangle for fixed point e.g. pixel coordinates */
95 struct _IntRectangle
{
98 int bottom
; /*!< y2 */
103 * \brief BezPoint is a bezier point forming _Bezierline or _Beziergon
107 BEZ_MOVE_TO
, /*!< move to point p1 */
108 BEZ_LINE_TO
, /*!< line to point p1 */
109 BEZ_CURVE_TO
/*!< curve to point p3 using p1 and p2 as control points */
111 Point p1
; /*!< main point in case of move or line-to, otherwise first control point */
112 Point p2
; /*!< second control point */
113 Point p3
; /*!< main point for 'true' bezier point */
117 #define ROUND(x) ((int) floor((x)+0.5))
119 /* inline these functions if the platform supports it */
121 G_INLINE_FUNC
void point_add(Point
*p1
, const Point
*p2
);
124 point_add(Point
*p1
, const Point
*p2
)
131 G_INLINE_FUNC
void point_sub(Point
*p1
, const Point
*p2
);
134 point_sub(Point
*p1
, const Point
*p2
)
141 G_INLINE_FUNC real
point_dot(const Point
*p1
, const Point
*p2
);
144 point_dot(const Point
*p1
, const Point
*p2
)
146 return p1
->x
*p2
->x
+ p1
->y
*p2
->y
;
150 G_INLINE_FUNC real
point_len(const Point
*p
);
153 point_len(const Point
*p
)
155 return sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
159 G_INLINE_FUNC
void point_scale(Point
*p
, real alpha
);
162 point_scale(Point
*p
, real alpha
)
169 G_INLINE_FUNC
void point_normalize(Point
*p
);
172 point_normalize(Point
*p
)
176 len
= sqrt(p
->x
*p
->x
+ p
->y
*p
->y
);
178 /* One could call it a bug to try normalizing a vector with
179 * len 0 and the result at least requires definition. But
180 * this is what makes the beziergon bounding box calculation
181 * work. What's the mathematical correct result of 0.0/0.0 ?
194 G_INLINE_FUNC
void point_rotate(Point
*p1
, const Point
*p2
);
197 point_rotate(Point
*p1
, const Point
*p2
)
199 p1
->x
= p1
->x
*p2
->x
- p1
->y
*p2
->y
;
200 p1
->y
= p1
->x
*p2
->y
+ p1
->y
*p2
->x
;
204 G_INLINE_FUNC
void point_get_normed(Point
*dst
, const Point
*src
);
207 point_get_normed(Point
*dst
, const Point
*src
)
211 len
= sqrt(src
->x
*src
->x
+ src
->y
*src
->y
);
213 dst
->x
= src
->x
/ len
;
214 dst
->y
= src
->y
/ len
;
218 G_INLINE_FUNC
void point_get_perp(Point
*dst
, const Point
*src
);
221 point_get_perp(Point
*dst
, const Point
*src
)
223 /* dst = the src vector, rotated 90deg counter clowkwise. src *must* be
224 normalized before. */
230 G_INLINE_FUNC
void point_copy(Point
*dst
, const Point
*src
);
233 point_copy(Point
*dst
, const Point
*src
)
235 /* Unfortunately, the compiler is not clever enough. And copying using
236 ints is faster if we don't computer based on the copied values, but
237 is slower if we have to make a FP reload afterwards.
238 point_copy() is meant for the latter case : then, the compiler is
239 able to shuffle and merge the FP loads. */
245 G_INLINE_FUNC
void point_add_scaled(Point
*dst
, const Point
*src
, real alpha
);
248 point_add_scaled(Point
*dst
, const Point
*src
, real alpha
)
250 /* especially useful if src is a normed vector... */
251 dst
->x
+= alpha
* src
->x
;
252 dst
->y
+= alpha
* src
->y
;
256 G_INLINE_FUNC
void point_copy_add_scaled(Point
*dst
, const Point
*src
,
261 point_copy_add_scaled(Point
*dst
, const Point
*src
,
262 const Point
*vct
, real alpha
)
264 /* especially useful if vct is a normed vector... */
265 dst
->x
= src
->x
+ (alpha
* vct
->x
);
266 dst
->y
= src
->y
+ (alpha
* vct
->y
);
270 void point_convex(Point
*dst
, const Point
*src1
, const Point
*src2
, real alpha
);
272 void rectangle_union(Rectangle
*r1
, const Rectangle
*r2
);
273 void int_rectangle_union(IntRectangle
*r1
, const IntRectangle
*r2
);
274 void rectangle_intersection(Rectangle
*r1
, const Rectangle
*r2
);
275 int rectangle_intersects(const Rectangle
*r1
, const Rectangle
*r2
);
276 int point_in_rectangle(const Rectangle
* r
, const Point
*p
);
277 int rectangle_in_rectangle(const Rectangle
* outer
, const Rectangle
*inner
);
278 void rectangle_add_point(Rectangle
*r
, const Point
*p
);
280 G_INLINE_FUNC gboolean
rectangle_equals(const Rectangle
*old_extents
,
281 const Rectangle
*new_extents
);
283 G_INLINE_FUNC gboolean
284 rectangle_equals(const Rectangle
*r1
, const Rectangle
*r2
)
286 return ( (r2
->left
== r1
->left
) &&
287 (r2
->right
== r1
->right
) &&
288 (r2
->top
== r1
->top
) &&
289 (r2
->bottom
== r1
->bottom
) );
293 G_INLINE_FUNC real
distance_point_point(const Point
*p1
, const Point
*p2
);
296 distance_point_point(const Point
*p1
, const Point
*p2
)
298 real dx
= p1
->x
- p2
->x
;
299 real dy
= p1
->y
- p2
->y
;
300 return sqrt(dx
*dx
+ dy
*dy
);
304 G_INLINE_FUNC
const Point
*closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
);
306 G_INLINE_FUNC
const Point
*
307 closest_to(const Point
*to
, const Point
*p1
, const Point
*p2
)
309 if (distance_point_point(to
,p1
) < distance_point_point(to
,p2
))
315 G_INLINE_FUNC real
distance_point_point_manhattan(const Point
*p1
,
319 distance_point_point_manhattan(const Point
*p1
, const Point
*p2
)
321 real dx
= p1
->x
- p2
->x
;
322 real dy
= p1
->y
- p2
->y
;
323 return ABS(dx
) + ABS(dy
);
327 real
distance_rectangle_point(const Rectangle
*rect
, const Point
*point
);
328 real
distance_line_point(const Point
*line_start
, const Point
*line_end
,
329 real line_width
, const Point
*point
);
331 real
distance_polygon_point(const Point
*poly
, guint npoints
,
332 real line_width
, const Point
*point
);
334 /* bezier distance calculations */
335 real
distance_bez_seg_point(const Point
*b1
, const Point
*b2
,
336 const Point
*b3
, const Point
*b4
,
337 real line_width
, const Point
*point
);
338 real
distance_bez_line_point(const BezPoint
*b
, guint npoints
,
339 real line_width
, const Point
*point
);
340 real
distance_bez_shape_point(const BezPoint
*b
, guint npoints
,
341 real line_width
, const Point
*point
);
343 real
distance_ellipse_point(const Point
*centre
, real width
, real height
,
344 real line_width
, const Point
*point
);
346 typedef real Vector
[3];
347 typedef Vector Matrix
[3];
349 void transform_point (Matrix
, Point
*, Point
*);
350 void mult_matrix (Matrix
, Matrix
);
351 void identity_matrix (Matrix
);
352 void translate_matrix (Matrix
, real
, real
);
353 void scale_matrix (Matrix
, real
, real
);
354 void rotate_matrix (Matrix
, real
);
355 void xshear_matrix (Matrix
, real
);
356 void yshear_matrix (Matrix
, real
);
358 real
dot2(Point
*p1
, Point
*p2
);
359 void line_coef(real
*a
, real
*b
, real
*c
, Point
*p1
, Point
*p2
);
360 real
line_to_point(real a
, real b
, real c
, Point
*p
);
361 void point_perp(Point
*p
, real a
, real b
, real c
, Point
*perp
);
362 void fillet(Point
*p1
, Point
*p2
, Point
*p3
, Point
*p4
,
363 real r
, Point
*c
, real
*pa
, real
*aa
);
364 real
point_cross(Point
*p1
, Point
*p2
);
365 Point
calculate_object_edge(Point
*objmid
, Point
*end
, DiaObject
*obj
);
369 #endif /* GEOMETRY_H */