BRL-CAD
polygon.h
Go to the documentation of this file.
1/* P O L Y G O N . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21/*----------------------------------------------------------------------*/
22/* @file polygon.h */
23/** @addtogroup bg_polygon */
24/** @{ */
25
26/**
27 * @brief Functions for working with polygons
28 */
29
30#ifndef BG_POLYGON_H
31#define BG_POLYGON_H
32
33#include "common.h"
34#include "vmath.h"
35#include "bu/color.h"
36#include "bn/tol.h"
37#include "bv/defines.h"
38#include "bg/defines.h"
39#include "bg/polygon_types.h"
40
41__BEGIN_DECLS
42
43/* TODO - the following are operations originally from libged - ultimately need
44 * to better integrate these and the other polygon routines. For now, trying
45 * to get all the related logic in the same place so it is clearer what we do
46 * and don't have, and make what we do have easier to reuse. */
47
48/*
49 * Weird upper limit from clipper ---> sqrt(2^63 -1)/2
50 * Probably should be sqrt(2^63 -1)
51 */
52#define CLIPPER_MAX 1518500249
53
54BG_EXPORT extern fastf_t
56 struct bg_polygon *gpoly,
57 fastf_t sf,
58 matp_t model2view,
60 );
61
62BG_EXPORT extern int
64 struct bg_polygon *polyA,
65 struct bg_polygon *polyB,
66 matp_t model2view,
67 const struct bn_tol *tol,
68 fastf_t iscale
69 );
70
71/* model2view and view2model may be NULL, if the polygons are coplanar */
72BG_EXPORT extern struct bg_polygon *
74 bg_clip_t op,
75 struct bg_polygon *subj,
76 struct bg_polygon *clip,
77 fastf_t sf,
78 matp_t model2view,
79 matp_t view2model
80 );
81
82/* model2view and view2model may be NULL, if the polygons are coplanar */
83BG_EXPORT extern struct bg_polygon *
85 bg_clip_t op,
86 struct bg_polygons *subj,
87 struct bg_polygons *clip,
88 fastf_t sf,
89 matp_t model2view,
90 matp_t view2model
91 );
92
93BG_EXPORT extern struct bg_polygon *
94bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t line_spacing);
95
96BG_EXPORT extern void bg_polygon_free(struct bg_polygon *gpp);
97BG_EXPORT extern void bg_polygons_free(struct bg_polygons *gpp);
98
99BG_EXPORT extern void bg_polygon_cpy(struct bg_polygon *dest, struct bg_polygon *src);
100
101
102/********************************
103 * Operations on 2D point types *
104 ********************************/
105
106/**
107 * @brief
108 * Test whether a polygon is clockwise (CW) or counter clockwise (CCW)
109 *
110 * Determine if a set of points forming a polygon are in clockwise
111 * or counter-clockwise order (see http://stackoverflow.com/a/1165943)
112 *
113 * @param[in] npts number of points in polygon
114 * @param[in] pts array of points
115 * @param[in] pt_indices index values into pts array building a convex polygon. duplicated points
116 * aren't allowed.
117 *
118 * If pt_indices is NULL, the first npts points in pts will be checked in array order.
119 *
120 * @return BG_CCW if polygon is counter-clockwise
121 * @return BG_CW if polygon is clockwise
122 * @return 0 if the test failed
123 */
124BG_EXPORT extern int bg_polygon_direction(size_t npts, const point2d_t *pts, const int *pt_indices);
125
126
127/**
128 * @brief
129 * test whether a point is inside a 2d polygon
130 *
131 * franklin's test for point inclusion within a polygon - see
132 * https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
133 * for more details and the implementation file polygon.c for license info.
134 *
135 * @param[in] npts number of points pts contains
136 * @param[in] pts array of points, building a convex polygon. duplicated points
137 * aren't allowed. the points in the array will be sorted counter-clockwise.
138 * @param[in] test_pt point to test.
139 *
140 * @return 0 if point is outside polygon
141 * @return 1 if point is inside polygon
142 */
143BG_EXPORT extern int bg_pnt_in_polygon(size_t npts, const point2d_t *pts, const point2d_t *test_pt);
144
145/**
146 * Triangulation is the process of finding a set of triangles that as a set cover
147 * the same total surface area as a polygon. There are many algorithms for this
148 * operation, which have various trade-offs in speed and output quality.
149 */
150typedef enum {
159
160/**
161 * @brief
162 * Triangulate a 2D polygon with holes.
163 *
164 * The primary polygon definition must be provided as an array of
165 * counter-clockwise indices to 2D points. If interior "hole" polygons are
166 * present, they must be passed in via the holes_array and their indices be
167 * ordered clockwise.
168 *
169 * If no holes are present, caller should pass NULL for holes_array and holes_npts,
170 * and 0 for nholes, or use bg_polygon_triangulate instead.
171 *
172 * @param[out] faces Set of faces in the triangulation, stored as integer indices to the pts. The first three indices are the vertices of the first face, the second three define the second face, and so forth.
173 * @param[out] num_faces Number of faces created
174 * @param[out] out_pts output points used by faces set. If an algorithm was selected that generates new points, this will be a new array.
175 * @param[out] num_outpts number of output points, if an algorithm was selected that generates new points
176 * @param[in] poly Non-hole polygon, defined as a CCW array of indices into the pts array.
177 * @param[in] poly_npts Number of points in non-hole polygon
178 * @param[in] holes_array Array of hole polygons, each defined as a CW array of indices into the pts array.
179 * @param[in] holes_npts Array of counts of points in hole polygons
180 * @param[in] nholes Number of hole polygons contained in holes_array
181 * @param[in] steiner Array of Steiner points
182 * @param[in] steiner_npts Number of Steiner points
183 * @param[in] pts Array of points defining a polygon. Duplicated points
184 * @param[in] npts Number of points pts contains
185 * @param[in] type Type of triangulation
186 *
187 * @return 0 if triangulation is successful
188 * @return 1 if triangulation is unsuccessful
189 */
190BG_EXPORT extern int bg_nested_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts,
191 const int *poly, const size_t poly_npts,
192 const int **holes_array, const size_t *holes_npts, const size_t nholes,
193 const int *steiner, const size_t steiner_npts,
194 const point2d_t *pts, const size_t npts, triangulation_t type);
195
196/**
197 * @brief
198 * Triangulate a 2D polygon without holes.
199 *
200 * The polygon cannot have holes and must be provided as an array of
201 * counter-clockwise 2D points.
202 *
203 * No points are added as part of this triangulation process - the result uses
204 * only those points in the original polygon, and hence only the face
205 * information is created as output.
206 *
207 * The same fundamental routines are used here as in the bg_nested_polygon_triangulate
208 * logic - this is a convenience function to simplify calling the routine when
209 * specification of hole polygons is not needed.
210 *
211 * @param[out] faces Set of faces in the triangulation, stored as integer indices to the pts. The first three indices are the vertices of the first face, the second three define the second face, and so forth.
212 * @param[out] num_faces Number of faces created
213 * @param[out] out_pts output points used by faces set, if an algorithm was selected that generates new points
214 * @param[out] num_outpts number of output points, if an algorithm was selected that generates new points
215 * @param[in] steiner Array of Steiner points
216 * @param[in] steiner_npts Number of Steiner points
217 * @param[in] pts Array of points defining a polygon. Duplicated points
218 * @param[in] npts Number of points pts contains
219 * @param[in] type Triangulation type
220 *
221 * @return 0 if triangulation is successful
222 * @return 1 if triangulation is unsuccessful
223 */
224BG_EXPORT extern int bg_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts,
225 const int *steiner, const size_t steiner_npts,
226 const point2d_t *pts, const size_t npts, triangulation_t type);
227
228
229/* Test function - do not use */
230BG_EXPORT extern int
231bg_poly2tri_test(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts,
232 const int *poly, const size_t poly_pnts,
233 const int **holes_array, const size_t *holes_npts, const size_t nholes,
234 const int *steiner, const size_t steiner_npts,
235 const point2d_t *pts);
236
237/*********************************************************
238 Operations on 3D point types - these are assumed to be
239 polygons embedded in 3D planes in space
240*********************************************************/
241
242/**
243 * @brief
244 * Calculate the interior area of a polygon in a 3D plane in space.
245 *
246 * If npts > 4, Greens Theorem is used. The polygon mustn't
247 * be self-intersecting.
248 *
249 * @param[out] area The interior area of the polygon
250 * @param[in] npts Number of point_ts, stored in pts
251 * @param[in] pts All points of the polygon, sorted counter-clockwise.
252 * The array mustn't contain duplicated or non-coplanar points.
253 *
254 * @return 0 if calculation was successful
255 * @return 1 if calculation failed, e.g. because one parameter is a NULL-pointer
256 */
257BG_EXPORT extern int bg_3d_polygon_area(fastf_t *area, size_t npts, const point_t *pts);
258
259
260/**
261 * @brief
262 * Calculate the centroid of a non self-intersecting polygon in a 3D plane in space.
263 *
264 * @param[out] cent The centroid of the polygon
265 * @param[in] npts Number of point_ts, stored in pts
266 * @param[in] pts all points of the polygon, sorted counter-clockwise.
267 * The array mustn't contain duplicated points or non-coplanar points.
268 *
269 * @return 0 if calculation was successful
270 * @return 1 if calculation failed, e.g. because one in-parameter is a NULL-pointer
271 */
272BG_EXPORT extern int bg_3d_polygon_centroid(point_t *cent, size_t npts, const point_t *pts);
273
274
275/**
276 * @brief
277 * Sort an array of point_ts, building a convex polygon, counter-clockwise
278 *
279 *@param[in] npts Number of points, pts contains
280 *@param pts Array of point_ts, building a convex polygon. Duplicated points
281 *aren't allowed. The points in the array will be sorted counter-clockwise.
282 *@param[in] cmp Plane equation of the polygon
283 *
284 *@return 0 if calculation was successful
285 *@return 1 if calculation failed, e.g. because pts is a NULL-pointer
286 */
287BG_EXPORT extern int bg_3d_polygon_sort_ccw(size_t npts, point_t *pts, plane_t cmp);
288
289
290/**
291 * @brief
292 * Calculate for an array of plane_eqs, which build a polyhedron, the
293 * point_t's for each face.
294 *
295 * @param[out] npts Array, which stores for every face the number of
296 * point_ts, added to pts. Needs to be allocated with npts[neqs] already.
297 * @param[out] pts 2D-array which stores the point_ts for every
298 * face. The array needs to be allocated with pts[neqs][neqs-1] already.
299 * @param[in] neqs Number of plane_ts, stored in eqs
300 * @param[in] eqs Array, that contains the plane equations, which
301 * build the polyhedron
302 *
303 * @return 0 if calculation was successful
304 * @return 1 if calculation failed, e.g. because one parameter is a NULL-Pointer
305 */
306BG_EXPORT extern int bg_3d_polygon_make_pnts_planes(size_t *npts, point_t **pts, size_t neqs, const plane_t *eqs);
307
308
309
310/* Debugging functions - do not use */
311BG_EXPORT extern void bg_polygon_plot_2d(const char *filename, const point2d_t *pnts, int npnts, int r, int g, int b);
312BG_EXPORT extern void bg_polygon_plot(const char *filename, const point_t *pnts, int npnts, int r, int g, int b);
313BG_EXPORT extern void bg_tri_plot_2d(const char *filename, const int *faces, int num_faces, const point2d_t *pnts, int r, int g, int b);
314
315
316/* BV related polygon logic and types */
317
318#define BV_POLYGON_GENERAL 0
319#define BV_POLYGON_CIRCLE 1
320#define BV_POLYGON_ELLIPSE 2
321#define BV_POLYGON_RECTANGLE 3
322#define BV_POLYGON_SQUARE 4
323
325 int type;
326 int fill_flag; /* set to shade the interior */
333
334 /* We stash the view state on creation, so we know how to return
335 * to it for future 2D alterations */
336 struct bview v;
337
338 /* Actual polygon info */
340
341 /* Arbitrary data */
342 void *u_data;
343};
344
345// Given a polygon, create a scene object
346BG_EXPORT extern struct bv_scene_obj *bv_create_polygon_obj(struct bview *v, struct bv_polygon *p);
347
348// Note - for these functions it is important that the bv
349// gv_width and gv_height values are current! I.e.:
350//
351// v->gv_width = dm_get_width((struct dm *)v->dmp);
352// v->gv_height = dm_get_height((struct dm *)v->dmp);
353
354// Creates a scene object with a default polygon
355BG_EXPORT extern struct bv_scene_obj *bv_create_polygon(struct bview *v, int type, int x, int y);
356
357// Various update modes have similar logic - we pass in the flags to the update
358// routine to enable/disable specific portions of the overall flow.
359#define BV_POLYGON_UPDATE_DEFAULT 0
360#define BV_POLYGON_UPDATE_PROPS_ONLY 1
361#define BV_POLYGON_UPDATE_PT_SELECT 2
362#define BV_POLYGON_UPDATE_PT_MOVE 3
363#define BV_POLYGON_UPDATE_PT_APPEND 4
364BG_EXPORT extern int bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype);
365
366// Update just the scene obj vlist, without altering the source polygon
367BG_EXPORT extern void bv_polygon_vlist(struct bv_scene_obj *s);
368
369// Find the closest polygon obj to a view's current x,y mouse points
370BG_EXPORT extern struct bv_scene_obj *bv_select_polygon(struct bu_ptbl *objs, struct bview *v);
371
372BG_EXPORT extern int bv_move_polygon(struct bv_scene_obj *s);
373BG_EXPORT extern struct bv_scene_obj *bg_dup_view_polygon(const char *nname, struct bv_scene_obj *s);
374
375
376// For all polygon objects in the objs table, apply the specified boolean op
377// using p and replace the original polygons in objs with the results (NOTE: p
378// will not act on itself if it is in objs):
379//
380// u : objs[i] u p (unions p with objs[i])
381// - : objs[i] - p (removes p from objs[i])
382// + : objs[i] + p (intersects p with objs[i])
383BG_EXPORT extern int bv_polygon_csg(struct bu_ptbl *objs, struct bv_scene_obj *p, bg_clip_t op, int merge);
384
385__END_DECLS
386
387#endif /* BG_POLYGON_H */
388/** @} */
389/*
390 * Local Variables:
391 * mode: C
392 * tab-width: 8
393 * indent-tabs-mode: t
394 * c-file-style: "stroustrup"
395 * End:
396 * ex: shiftwidth=4 tabstop=8
397 */
Header file for the BRL-CAD common definitions.
void bg_polygon_plot(const char *filename, const point_t *pnts, int npnts, int r, int g, int b)
struct bv_scene_obj * bv_create_polygon_obj(struct bview *v, struct bv_polygon *p)
struct bg_polygon * bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t line_spacing)
int bg_polygon_direction(size_t npts, const point2d_t *pts, const int *pt_indices)
Test whether a polygon is clockwise (CW) or counter clockwise (CCW)
triangulation_t
Definition: polygon.h:150
int bg_3d_polygon_centroid(point_t *cent, size_t npts, const point_t *pts)
Calculate the centroid of a non self-intersecting polygon in a 3D plane in space.
int bg_polygons_overlap(struct bg_polygon *polyA, struct bg_polygon *polyB, matp_t model2view, const struct bn_tol *tol, fastf_t iscale)
struct bv_scene_obj * bv_create_polygon(struct bview *v, int type, int x, int y)
struct bv_scene_obj * bv_select_polygon(struct bu_ptbl *objs, struct bview *v)
int bg_3d_polygon_area(fastf_t *area, size_t npts, const point_t *pts)
Calculate the interior area of a polygon in a 3D plane in space.
void bv_polygon_vlist(struct bv_scene_obj *s)
int bg_pnt_in_polygon(size_t npts, const point2d_t *pts, const point2d_t *test_pt)
test whether a point is inside a 2d polygon
void bg_polygon_cpy(struct bg_polygon *dest, struct bg_polygon *src)
void bg_tri_plot_2d(const char *filename, const int *faces, int num_faces, const point2d_t *pnts, int r, int g, int b)
void bg_polygons_free(struct bg_polygons *gpp)
bg_clip_t
Functions for working with polygons.
Definition: polygon_types.h:40
struct bv_scene_obj * bg_dup_view_polygon(const char *nname, struct bv_scene_obj *s)
int bv_polygon_csg(struct bu_ptbl *objs, struct bv_scene_obj *p, bg_clip_t op, int merge)
struct bg_polygon * bg_clip_polygon(bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, fastf_t sf, matp_t model2view, matp_t view2model)
int bg_poly2tri_test(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, const int *poly, const size_t poly_pnts, const int **holes_array, const size_t *holes_npts, const size_t nholes, const int *steiner, const size_t steiner_npts, const point2d_t *pts)
int bg_3d_polygon_sort_ccw(size_t npts, point_t *pts, plane_t cmp)
Sort an array of point_ts, building a convex polygon, counter-clockwise.
int bg_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, const int *steiner, const size_t steiner_npts, const point2d_t *pts, const size_t npts, triangulation_t type)
Triangulate a 2D polygon without holes.
int bg_nested_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, const int *poly, const size_t poly_npts, const int **holes_array, const size_t *holes_npts, const size_t nholes, const int *steiner, const size_t steiner_npts, const point2d_t *pts, const size_t npts, triangulation_t type)
Triangulate a 2D polygon with holes.
int bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype)
int bg_3d_polygon_make_pnts_planes(size_t *npts, point_t **pts, size_t neqs, const plane_t *eqs)
Calculate for an array of plane_eqs, which build a polyhedron, the point_t's for each face.
struct bg_polygon * bg_clip_polygons(bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *clip, fastf_t sf, matp_t model2view, matp_t view2model)
void bg_polygon_plot_2d(const char *filename, const point2d_t *pnts, int npnts, int r, int g, int b)
void bg_polygon_free(struct bg_polygon *gpp)
int bv_move_polygon(struct bv_scene_obj *s)
fastf_t bg_find_polygon_area(struct bg_polygon *gpoly, fastf_t sf, matp_t model2view, fastf_t size)
@ TRI_MONOTONE
Definition: polygon.h:154
@ TRI_ANY
Definition: polygon.h:151
@ TRI_KEIL_SNOEYINK
Definition: polygon.h:156
@ TRI_DELAUNAY
Definition: polygon.h:157
@ TRI_HERTEL_MEHLHORN
Definition: polygon.h:155
@ TRI_CONSTRAINED_DELAUNAY
Definition: polygon.h:153
@ TRI_EAR_CLIPPING
Definition: polygon.h:152
void float float * y
Definition: tig.h:73
void float float int int int int float * size
Definition: tig.h:132
void float * x
Definition: tig.h:72
int clip(fastf_t *, fastf_t *, fastf_t *, fastf_t *)
double fastf_t
fastest 64-bit (or larger) floating point type
Definition: vmath.h:330
fastf_t point2d_t[ELEMENTS_PER_POINT2D]
2-tuple point
Definition: vmath.h:339
fastf_t plane_t[ELEMENTS_PER_PLANE]
Definition of a plane equation.
Definition: vmath.h:393
fastf_t * matp_t
pointer to a 4x4 matrix
Definition: vmath.h:369
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:351
fastf_t vect2d_t[ELEMENTS_PER_VECT2D]
2-tuple vector
Definition: vmath.h:333
Definition: tol.h:72
Definition: color.h:54
Definition: ptbl.h:53
vect2d_t fill_dir
Definition: polygon.h:327
struct bg_polygon polygon
Definition: polygon.h:339
fastf_t fill_delta
Definition: polygon.h:328
point_t prev_point
Definition: polygon.h:332
int fill_flag
Definition: polygon.h:326
long curr_point_i
Definition: polygon.h:331
void * u_data
Definition: polygon.h:342
struct bview v
Definition: polygon.h:336
int type
Definition: polygon.h:325
long curr_contour_i
Definition: polygon.h:330
struct bu_color fill_color
Definition: polygon.h:329
Definition: defines.h:476
fundamental vector, matrix, quaternion math macros