Library of Assembled Shared Sources
degenerate_policy.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2023 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45/** @defgroup DegeneratePolicy DegeneratePolicy
46 * @brief policies to specify the rules for degenerate polygons and others..
47 * @author Bram de Greve
48 * @date 2003
49 *
50 * Polygons and triangles can be degenerate. e.g. when they have less than
51 * 3 vertices, or some vertices are coincident, or colinear. We provide a few
52 * policies to deal with this.
53 */
54
55#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_DEGENERATE_POLICY_H
56#define LASS_GUARDIAN_OF_INCLUSION_PRIM_DEGENERATE_POLICY_H
57
58
59#include "prim_common.h"
60#include "../util/enforcer.h"
61
62namespace lass
63{
64namespace prim
65{
66
67/** @ingroup DegeneratePolicy
68 */
69class DegenerationError: public util::ExceptionMixin<DegenerationError>
70{
71public:
72 DegenerationError(std::string msg, std::string loc): util::ExceptionMixin<DegenerationError>(std::move(msg), std::move(loc)) {}
73 ~DegenerationError() noexcept {}
74};
75
76
77
78/** @ingroup DegeneratePolicy
79 *
80 * This is the default policy
81 *
82 * NoDegenerate will not prevent a primitive to become degenerate, but it will check some
83 * basic conditions when you try to do "unsafe" operations and throws
84 * an exception on failure. e.g. CheckDegenerate will not allow you to get the @c edge(0)
85 * or @c vector(0) of a polygon with only one vertex.
86 *
87 * However, it will not check all posible conditions. It will avoid expensive predicates.
88 * e.g. it will avoid to test if a polygon is simple, because that's too expensive. If you
89 * want all conditions to be checked, you should use StrictNoDegenerate
90 */
92{
93 template <class Primitive>
94 static void enforceEdge(const Primitive& iPrimitive, int iIndexOfTailVertex)
95 {
96 if (iPrimitive.at(iIndexOfTailVertex) == iPrimitive.at(iIndexOfTailVertex + 1))
97 {
98 LASS_THROW_EX(DegenerationError, "Degenerate edge detected at tail vertex '" << iIndexOfTailVertex << "'.");
99 }
100 }
101
102 template <class Primitive>
103 static void enforceSimple(const Primitive& /*iPrimitive*/)
104 {
105 }
106
107 template <class Primitive>
108 static const typename Primitive::TValue enforceNonZeroSignedArea(const Primitive& iPrimitive)
109 {
110 const typename Primitive::TValue result = iPrimitive.signedArea();
111 if (result == Primitive::TNumTraits::zero)
112 {
113 LASS_THROW_EX(DegenerationError, "Area of primitive is zero.");
114 }
115 return result;
116 }
117};
118
119
120
121/** @ingroup DegeneratePolicy
122 *
123 * This is the default policy
124 *
125 * StrictNoDegenerate is similar to NoDegenerate, but will check more conditions. However, this
126 * might go wild on cpu usage (read: be very slow). Use this if you really need to be on the safe
127 * side.
128 */
130{
131 template <class Primitive>
132 static void enforceEdge(const Primitive& iPrimitive, int iIndexOfTailVertex)
133 {
134 if (iPrimitive.at(iIndexOfTailVertex) == iPrimitive.at(iIndexOfTailVertex + 1))
135 {
136 LASS_THROW_EX(DegenerationError, "Degenerate edge detected at tail vertex '" << iIndexOfTailVertex << "'.");
137 }
138 }
139
140 template <class Primitive>
141 static void enforceSimple(const Primitive& iPrimitive)
142 {
143 if (!iPrimitive.isSimple())
144 {
145 LASS_THROW_EX(DegenerationError, "polygon is not simple.");
146 }
147 }
148
149 template <class Primitive>
150 static const typename Primitive::TValue enforceNonZeroSignedArea(const Primitive& iPrimitive)
151 {
152 const typename Primitive::TValue result = iPrimitive.signedArea();
153 if (result == Primitive::TNumTraits::zero)
154 {
155 LASS_THROW_EX(DegenerationError, "Area of primitive is zero.");
156 }
157 return result;
158 }
159};
160
161
162
163/** @ingroup DegeneratePolicy
164 *
165 * AllowDegenerate puts the responsibility on the user. It will assume all conditions are fullfilled
166 * and continue like nothing is wrong. This is the "best guess" thing.
167 */
169{
170 template <class Primitive>
171 static void enforceEdge(const Primitive& /*iPrimitive*/, int /*iIndexOfTailVertex*/)
172 {
173 }
174
175 template <class Primitive>
176 static void enforceSimple(const Primitive& /*iPrimitive*/)
177 {
178 }
179
180 template <class Primitive>
181 static const typename Primitive::TValue enforceNonZeroSignedArea(const Primitive& iPrimitive)
182 {
183 return iPrimitive.signedArea();
184 }
185};
186
187
188}
189
190}
191
192// --- implementation ------------------------------------------------------------------------------
193
194namespace lass
195{
196namespace prim
197{
198namespace impl
199{
200
201/** raises exception in case primitive is degenerate and we have restricting
202 * @relates lass::prim::Bounded
203 */
204/*
205struct DegenerateRaiser
206{
207 template <class T>
208 static void raise(const T&, const std::string& iMessage, const char* iLocus)
209 {
210 LASS_THROW_EX(DegenerationError, iMessage << '\n' << iLocus);
211 }
212};
213*/
214
215}
216
217}
218
219}
220
221
222
223#endif
224
225// EOF
set of geometrical primitives
Definition aabb_2d.h:81
Library for Assembled Shared Sources.
Definition config.h:53
AllowDegenerate puts the responsibility on the user.
This is the default policy.
This is the default policy.