source: cpp/frams/model/geometry/geometryutils.h @ 1045

Last change on this file since 1045 was 1045, checked in by oriona, 3 months ago

Part of GeometryTestUtils? functions moved to GeometryUtils?.

  • Property svn:eol-style set to native
File size: 9.2 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#ifndef _GEOMETRYUTILS_H_
6#define _GEOMETRYUTILS_H_
7
8#include <frams/model/model.h>
9#include <frams/model/modelparts.h>
10#include <frams/util/3d.h>
11#include <frams/util/list.h>
12
13
14/*Binary literals like 0b010 are standardized only in C++14. We use macros as they are compatible with older compilers too.
15
163-bit numbers are used when iterating through octants in a 3D space. Example: when creating points that cover the surface
17of an ellipsoid, the points are only created for the positive octant (x, y, and z coordinates are positive). Points in
18the remaining 7 octants are created by reflecting points from the positive octant through the appropriate planes defined by
19pairs of axes.
20
212-bit numbers are used for 2D. Example: cylinders are aligned along the x axis so that both bases are parallel to
22the yz plane. When points are created along the edge of the base (these will be used later to create points along the side
23of the cylinder), only y and z axes are important, so quadrants of the 2D are sufficient. Just as in the 3D example above,
24only points for the positive quadrant, QuadrantYZ, are created, and points of the remaining quadrants are created by reflection.
25QuadrantXY and QuadrantZX enumerations are never used and are provided only for completeness.
26*/
27#define b000 0
28#define b01 1
29#define b001 1
30#define b10 2
31#define b010 2
32#define b100 4
33#define b110 6
34
35
36
37namespace CuboidFaces
38{
39        enum Face
40        {
41                NEGATIVE_X = 0,
42                POSITIVE_X = 1,
43                NEGATIVE_Y = 2,
44                POSITIVE_Y = 3,
45                NEGATIVE_Z = 4,
46                POSITIVE_Z = 5,
47                FIRST = 0,
48                NUMBER = 6
49        };
50       
51        inline bool isPositive(Face f) { return f & b001; }
52        inline bool isNegative(Face f) { return !isPositive(f); }
53        inline bool isX(Face f) { return (f & b110) == b000; }
54        inline bool isY(Face f) { return (f & b110) == b010; }
55        inline bool isZ(Face f) { return (f & b110) == b100; }
56}
57
58namespace CylinderBases
59{
60        enum Base
61        {
62                NEGATIVE_X = 0,
63                POSITIVE_X = 1,
64                FIRST = 0,
65                NUMBER = 2
66        };
67       
68        inline bool isPositive(Base b) { return b & b001; }
69        inline bool isNegative(Base b) { return !isPositive(b); }
70}
71
72namespace QuadrantsXY
73{
74        enum QuadrantXY
75        {
76                NEGATIVE_X_NEGATIVE_Y = 0,
77                NEGATIVE_X_POSITIVE_Y = 1,
78                POSITIVE_X_NEGATIVE_Y = 2,
79                POSITIVE_X_POSITIVE_Y = 3,
80                FIRST = 0,
81                NUMBER = 4
82        };
83       
84        inline bool isPositiveX(QuadrantXY q) { return (q & b10) != 0; }
85        inline bool isNegativeX(QuadrantXY q) { return !isPositiveX(q); }
86        inline bool isPositiveY(QuadrantXY q) { return q & b01; }
87        inline bool isNegativeY(QuadrantXY q) { return !isPositiveY(q); }
88}
89
90namespace QuadrantsYZ
91{
92        enum QuadrantYZ
93        {
94                NEGATIVE_Y_NEGATIVE_Z = 0,
95                NEGATIVE_Y_POSITIVE_Z = 1,
96                POSITIVE_Y_NEGATIVE_Z = 2,
97                POSITIVE_Y_POSITIVE_Z = 3,
98                FIRST = 0,
99                NUMBER = 4
100        };
101       
102        inline bool isPositiveY(QuadrantYZ q) { return (q & b10) != 0; }
103        inline bool isNegativeY(QuadrantYZ q) { return !isPositiveY(q); }
104        inline bool isPositiveZ(QuadrantYZ q) { return q & b01; }
105        inline bool isNegativeZ(QuadrantYZ q) { return !isPositiveZ(q); }
106}
107
108namespace QuadrantsZX
109{
110        enum QuadrantZX
111        {
112                NEGATIVE_Z_NEGATIVE_X = 0,
113                NEGATIVE_Z_POSITIVE_X = 1,
114                POSITIVE_Z_NEGATIVE_X = 2,
115                POSITIVE_Z_POSITIVE_X = 3,
116                FIRST = 0,
117                NUMBER = 4
118        };
119       
120        inline bool isPositiveZ(QuadrantZX q) { return (q & b10) != 0; }
121        inline bool isNegativeZ(QuadrantZX q) { return !isPositiveZ(q); }
122        inline bool isPositiveX(QuadrantZX q) { return (q & b01) != 0; }
123        inline bool isNegativeX(QuadrantZX q) { return !isPositiveX(q); }
124}
125
126namespace Octants
127{
128        enum Octant
129        {
130                NEGATIVE_X_NEGATIVE_Y_NEGATIVE_Z = 0,
131                NEGATIVE_X_NEGATIVE_Y_POSITIVE_Z = 1,
132                NEGATIVE_X_POSITIVE_Y_NEGATIVE_Z = 2,
133                NEGATIVE_X_POSITIVE_Y_POSITIVE_Z = 3,
134                POSITIVE_X_NEGATIVE_Y_NEGATIVE_Z = 4,
135                POSITIVE_X_NEGATIVE_Y_POSITIVE_Z = 5,
136                POSITIVE_X_POSITIVE_Y_NEGATIVE_Z = 6,
137                POSITIVE_X_POSITIVE_Y_POSITIVE_Z = 7,
138                FIRST = 0,
139                NUMBER = 8
140        };
141       
142        inline bool isPositiveX(Octant o) { return (o & b100) != 0; }
143        inline bool isNegativeX(Octant o) { return !isPositiveX(o); }
144        inline bool isPositiveY(Octant o) { return (o & b010) != 0; }
145        inline bool isNegativeY(Octant o) { return !isPositiveY(o); }
146        inline bool isPositiveZ(Octant o) { return o & b001; }
147        inline bool isNegativeZ(Octant o) { return !isPositiveZ(o); }
148}
149
150namespace GeometryUtils
151{
152        double pointPosition(const int pointIndex, const int numberOfPoints);
153        double pointOnAxis(const double scale, const double position);
154        double pointOnAxis(const double scale, const int pointIndex, const int numberOfPoints);
155        double combination(const double value1, const double value2, const double position);
156        double combination(const double value1, const double value2, const int pointIndex, const int numberOfPoints);
157        bool isPointInsideModelExcludingPart(const Pt3D &point, const Model *model, const int excludedPartIndex);
158        bool isPointInsideModel(const Pt3D &point, const Model &model);
159        bool isPointInsidePart(const Pt3D &point, const Part *part);
160        bool isPointStrictlyInsidePart(const Pt3D &point, const Part *part);
161        bool isPointInsideEllipsoid(const Pt3D &point, const Part *part);
162        bool isPointStrictlyInsideEllipsoid(const Pt3D &point, const Part *part);
163        bool isPointInsideCuboid(const Pt3D &point, const Part *part);
164        bool isPointStrictlyInsideCuboid(const Pt3D &point, const Part *part);
165        bool isPointInsideCylinder(const Pt3D &point, const Part *part);
166        bool isPointStrictlyInsideCylinder(const Pt3D &point, const Part *part);
167        void findSizesAndAxesOfPointsGroup(SListTempl<Pt3D> &points, Pt3D &sizes, Orient &axes);
168        void findSizeAndAxisOfPointsGroup(const SListTempl<Pt3D> &points, double &size, Pt3D &axis);
169        double findTwoFurthestPoints(const SListTempl<Pt3D> &points, int &index1, int &index2);
170        void createAxisFromTwoPoints(Pt3D &axis, const Pt3D &point1, const Pt3D &point2);
171        void orthographicProjectionToPlane(SListTempl<Pt3D> &points, const Pt3D &planeNormalVector);
172        double pointDistanceToPlane(const Pt3D &point, const Pt3D &planeNormalVector);
173        void getRectangleApicesFromCuboid(const Part *part, const CuboidFaces::Face face, Pt3D &apex1, Pt3D &apex2, Pt3D &apex3, Pt3D &apex4);
174        void getRectangleApices(const double width, const double height, const Pt3D &position, const Orient &orient, Pt3D &apex1, Pt3D &apex2, Pt3D &apex3, Pt3D &apex4);
175        void getNextEllipseSegmentationPoint(const double d, const double a, const double b, double &x, double &y);
176        double ellipsoidArea(const Pt3D &sizes);
177        double ellipsoidArea(const double a, const double b, const double c);
178        double ellipsePerimeter(const double a, const double b);
179
180        double calculateSolidVolume(Part *part);
181        bool isSolidPartScaleValid(const Part::Shape &partShape, const Pt3D &scale);
182
183    /**
184    * @brief Adds anchor to the specified Model.
185    * @details An anchor has two functions. First is to provide Model consistency. Some functions in
186    *     GeometryTestUtils namespace requires Model passed to them as an argument to contain at
187    *     least one Part. All new Parts are bonded to the rest of Model using Joint connecting them
188    *     with first Part of Model. Second is to provide reference which helps to understand Model
189    *     position, scale and orientation. Anchor is built from four Parts: small sphere placed in
190    *     global coordinate system origin and three cuboids visualising global coordinate system
191    *     axes.
192    * @see addAxesToModel.
193    * @param[in] model Owner of Parts to be created.
194    */
195    void addAnchorToModel(Model &model);
196
197    /**
198     * @brief Adds point marker to Model.
199     * @details Marker of point is a small sphere (radius = 0.05).
200     * @param[in] point Location of marker.
201     * @param[in] model Owner of Part to be created, must contain at least one part.
202     */
203    void addPointToModel(const Pt3D &point, Model &model);
204
205    /**
206     * @brief Adds axes markers to Model.
207     * @details Axes markers are three streched (one of scales = 0.5, others = 0.05) and colored
208     *     cuboids. Cuboid visualising OX axis is red, OY - green, and OZ - blue.
209     * @param[in] sizes Axes visual lengths.
210     * @param[in] axes Axes orientation, relatively to global coordinate system axes.
211     * @param[in] center Axes intersection point, relatively to global coordinate system origin.
212     * @param[in] model Owner of Parts to be created, must contain at least one part.
213     */
214    void addAxesToModel(const Pt3D &sizes, const Orient &axes, const Pt3D &center, Model &model);
215
216    /**
217     * @brief Merges two Models.
218     * @details Moves all parts from source Model to target Model and - to provide Model
219     *     consistency - creates Joint between firsts Parts of each of them. Each model must contain
220     *     at least one Part.
221     * @param[in] target Target Model, must contain at least one part.
222     * @param[in] source Source Model, must contain at least one part.
223     */
224    void mergeModels(Model &target, Model &source);
225
226    /**
227     * @brief Randomizes position, scale and rotations of Part.
228     * @details Sets coords of Part position to random values from range (1.5, 2.5), scales to
229     *     random values from range (0.1, 1.0), and rotations around each axis to random values from
230     *     range (0, M_PI).
231     * @param[in] part Part which position, scale and orient should be randomized.
232     */
233    void randomizePositionScaleAndOrient(Part *part);
234}
235
236#endif
Note: See TracBrowser for help on using the repository browser.