Ponca  84886bac0b52a686e88046a375da13f12f2b87d2
Point Cloud Analysis library
Loading...
Searching...
No Matches
pointGeneration.h
1/*
2This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7#pragma once
8
13#include "Eigen/Eigen"
14
15#define MIN_NOISE 0.99
16#define MAX_NOISE 1.01
17
18namespace Ponca {
19
21 template<typename DataPoint>
22 [[nodiscard]] DataPoint getPointOnSphere(
23 const typename DataPoint::Scalar _radius,
24 const typename DataPoint::VectorType _vCenter,
25 const bool _bAddPositionNoise = true,
26 const bool _bAddNormalNoise = true,
27 const bool _bReverseNormals = false
28 ) {
29 typedef typename DataPoint::Scalar Scalar;
30 typedef typename DataPoint::VectorType VectorType;
31
32 VectorType vNormal = VectorType::Random().normalized();
33 VectorType vPosition = _vCenter + vNormal * _radius;
34
35 if(_bAddPositionNoise)
36 {
37 vPosition = vPosition + VectorType::Random().normalized() *
38 Eigen::internal::random<Scalar>(Scalar(0.), Scalar(1. - MIN_NOISE));
39 vNormal = (vPosition - _vCenter).normalized();
40 }
41
42 if(_bAddNormalNoise)
43 {
44 VectorType vTempPos = vPosition + VectorType::Random().normalized() *
45 Eigen::internal::random<Scalar>(Scalar(0.), Scalar(1. - MIN_NOISE));
46 vNormal = (vTempPos - _vCenter).normalized();
47 }
48 if(_bReverseNormals)
49 {
50 const float reverse = Eigen::internal::random<float>(0.f, 1.f);
51 if(reverse > 0.5f)
52 vNormal = -vNormal;
53 }
54
55 return DataPoint(vPosition, vNormal);
56 }
57
59 template<typename DataPoint>
60 [[nodiscard]] DataPoint getPointOnRectangularPlane(
61 const typename DataPoint::VectorType& _vPosition,
62 const typename DataPoint::VectorType& /*_vNormal*/,
63 const typename DataPoint::Scalar& _width,
64 const typename DataPoint::Scalar& _height,
65 const typename DataPoint::VectorType& _localxAxis,
66 const typename DataPoint::VectorType& _localyAxis,
67 const bool _bAddPositionNoise = true
68 ) {
69 typedef typename DataPoint::Scalar Scalar;
70 typedef typename DataPoint::VectorType VectorType;
71
72 const Scalar u = Eigen::internal::random<Scalar>(
73 -_width /Scalar(2), _width /Scalar(2) );
74 const Scalar v = Eigen::internal::random<Scalar>(
75 -_height/Scalar(2), _height/Scalar(2) );
76
77 VectorType vRandomPosition = _vPosition + u*_localxAxis + v*_localyAxis;
78
79 if(_bAddPositionNoise)
80 {
81 vRandomPosition = vRandomPosition +
82 VectorType::Random().normalized() *
83 Eigen::internal::random<Scalar>(0., 1. - MIN_NOISE);
84 }
85
86 return DataPoint(vRandomPosition);
87 }
88
90 template<typename DataPoint>
91 [[nodiscard]] DataPoint getPointOnPlane(
92 const typename DataPoint::VectorType _vPosition,
93 const typename DataPoint::VectorType _vNormal,
94 const typename DataPoint::Scalar _radius,
95 const bool _bAddPositionNoise = true,
96 const bool _bAddNormalNoise = true,
97 const bool _bReverseNormals = false
98 ) {
99 typedef typename DataPoint::Scalar Scalar;
100 typedef typename DataPoint::VectorType VectorType;
101 typedef Eigen::Quaternion<Scalar> QuaternionType;
102
103 VectorType vRandom;
104 VectorType vRandomDirection = VectorType::Zero();
105 VectorType vRandomPoint = VectorType::Zero();
106 VectorType vLocalUp = _vNormal;
107
108 do
109 {
110 vRandom = VectorType::Random().normalized(); // Direction in the unit sphere
111 vRandomDirection = vRandom.cross(vLocalUp);
112 }
113 while(vRandomDirection == VectorType::Zero());
114
115 vRandomDirection = vRandomDirection.normalized();
116 vRandomPoint = vRandomDirection * _radius;
117 vRandomPoint += _vPosition;
118
119 if(_bAddPositionNoise)
120 {
121 vRandomPoint = vRandomPoint + VectorType::Random().normalized() *
122 Eigen::internal::random<Scalar>(Scalar(0), Scalar(1. - MIN_NOISE));
123 }
124
125 if(_bAddNormalNoise)
126 {
127 VectorType vLocalLeft = vLocalUp.cross(vRandomDirection);
128 VectorType vLocalFront = vLocalLeft.cross(vLocalUp);
129
130 Scalar rotationAngle = Eigen::internal::random<Scalar>(Scalar(-M_PI / 16.), Scalar(M_PI / 16.));
131 VectorType vRotationAxis = vLocalLeft;
132 QuaternionType qRotation = QuaternionType(Eigen::AngleAxis<Scalar>(rotationAngle, vRotationAxis));
133 qRotation = qRotation.normalized();
134 vLocalUp = qRotation * vLocalUp;
135
136 rotationAngle = Eigen::internal::random<Scalar>(Scalar(-M_PI / 16.), Scalar(M_PI / 16.));
137 vRotationAxis = vLocalFront;
138 qRotation = QuaternionType(Eigen::AngleAxis<Scalar>(rotationAngle, vRotationAxis));
139 qRotation = qRotation.normalized();
140 vLocalUp = qRotation * vLocalUp;
141 }
142
143 if(_bReverseNormals)
144 {
145 const float reverse = Eigen::internal::random<float>(0.f, 1.f);
146 if(reverse > 0.5f)
147 vLocalUp = -vLocalUp;
148
149 }
150
151 return DataPoint(vRandomPoint, vLocalUp);
152 }
153
154 namespace internal {
156 template<typename Scalar>
157 [[nodiscard]] inline Scalar getParaboloidZ(
158 const Scalar _x,
159 const Scalar _y,
160 const Scalar _a,
161 const Scalar _b
162 ) {
163 return _a*_x*_x + _b*_y*_y;
164 }
165
167 template<typename VectorType>
168 [[nodiscard]] inline VectorType getParaboloidNormal(
169 const VectorType& in,
170 const typename VectorType::Scalar _a,
171 const typename VectorType::Scalar _b
172 ) {
173 return VectorType((_a * in.x()), (_b * in.y()), -1.).normalized();;
174 }
175 }
176
181 template<typename DataPoint>
182 [[nodiscard]] DataPoint getPointOnParaboloid(
183 const typename DataPoint::Scalar _a,
184 const typename DataPoint::Scalar _b,
185 const typename DataPoint::Scalar _s,
186 const bool _bAddNoise = true
187 ) {
188 typedef typename DataPoint::Scalar Scalar;
189 typedef typename DataPoint::VectorType VectorType;
190
191 VectorType vNormal;
192 VectorType vPosition;
193
194 const Scalar x = Eigen::internal::random<Scalar>(-_s, _s),
195 y = Eigen::internal::random<Scalar>(-_s, _s);
196
197 vPosition = { x, y, internal::getParaboloidZ(x, y, _a, _b)};
198 vNormal = internal::getParaboloidNormal(vPosition, _a, _b);
199
200 if(_bAddNoise) // spherical noise
201 vPosition += VectorType::Random().normalized() * Eigen::internal::random<Scalar>(Scalar(0), Scalar(1. - MIN_NOISE));
202
203 return DataPoint(vPosition, vNormal);
204 }
205
207 template<typename DataPoint>
208 [[nodiscard]] DataPoint getRandomPoint() {
209 typedef typename DataPoint::VectorType VectorType;
210 typedef typename DataPoint::Scalar Scalar;
211 const VectorType n = VectorType::Random().normalized();
212 const VectorType p = n * Eigen::internal::random<Scalar>(MIN_NOISE, MAX_NOISE);
213 return {p, (n + VectorType::Random()*Scalar(0.1)).normalized()};
214 }
215}
This Source Code Form is subject to the terms of the Mozilla Public License, v.
DataPoint getPointOnPlane(const typename DataPoint::VectorType _vPosition, const typename DataPoint::VectorType _vNormal, const typename DataPoint::Scalar _radius, const bool _bAddPositionNoise=true, const bool _bAddNormalNoise=true, const bool _bReverseNormals=false)
Generate points on a plane.
DataPoint getPointOnParaboloid(const typename DataPoint::Scalar _a, const typename DataPoint::Scalar _b, const typename DataPoint::Scalar _s, const bool _bAddNoise=true)
Generate point samples on the primitive z = ax^2 + by^2.
DataPoint getRandomPoint()
Generate a random points.
DataPoint getPointOnSphere(const typename DataPoint::Scalar _radius, const typename DataPoint::VectorType _vCenter, const bool _bAddPositionNoise=true, const bool _bAddNormalNoise=true, const bool _bReverseNormals=false)
Generate points on a sphere.
DataPoint getPointOnRectangularPlane(const typename DataPoint::VectorType &_vPosition, const typename DataPoint::VectorType &, const typename DataPoint::Scalar &_width, const typename DataPoint::Scalar &_height, const typename DataPoint::VectorType &_localxAxis, const typename DataPoint::VectorType &_localyAxis, const bool _bAddPositionNoise=true)
Generate points on a plane without normals.