41 bool Init(
bool binary, std::istream* i);
43 void Init(
float* array);
44 inline float Distance(
const Vec3f& p)
const;
45 inline void Normal(
const Vec3f& p,
Vec3f* normal)
const;
46 inline float DistanceAndNormal(
const Vec3f& p,
Vec3f* normal)
const;
47 inline float SignedDistance(
const Vec3f& p)
const;
68 template <
class IteratorT>
69 bool LeastSquaresFit(IteratorT begin, IteratorT end);
76 return LeastSquaresFit(
pc, begin, end);
82 void Serialize(
bool binary, std::ostream* o)
const;
83 static size_t SerializedSize();
84 void Serialize(FILE* o)
const;
85 void Serialize(
float* array)
const;
86 static size_t SerializedFloatSize();
88 void Transform(
float scale,
const Vec3f& translate);
90 Intersect(
const Vec3f& p,
const Vec3f& r,
float* first,
float* second)
const;
93 template <
class WeightT>
94 class LevMarSimpleSphere :
public WeightT
102 typedef float ScalarType;
104 template <
class IteratorT>
106 Chi(
const ScalarType* params,
110 ScalarType* temp)
const
113 int size = end - begin;
114 #pragma omp parallel for schedule(static) reduction(+ : chi)
115 for (
int idx = 0; idx < size; ++idx)
117 float s = begin[idx][0] - params[0];
119 for (
unsigned int j = 1; j < 3; ++j)
121 float ss = begin[idx][j] - params[j];
130 template <
class IteratorT>
132 Derivatives(
const ScalarType* params,
136 const ScalarType* temp,
137 ScalarType* matrix)
const
139 int size = end - begin;
140 #pragma omp parallel for schedule(static)
141 for (
int idx = 0; idx < size; ++idx)
144 s[0] = begin[idx][0] - params[0];
145 float sl =
s[0] *
s[0];
146 for (
unsigned int i = 1; i < 3; ++i)
148 s[i] = begin[idx][i] - params[i];
152 matrix[idx * NumParams + 0] = -
s[0] / sl;
153 matrix[idx * NumParams + 1] = -
s[1] / sl;
154 matrix[idx * NumParams + 2] = -
s[2] / sl;
155 matrix[idx * NumParams + 3] = -1;
156 WeightT::template DerivWeigh<NumParams>(sl - params[3], matrix + idx * NumParams);
161 Normalize(ScalarType*)
const
166 template <
class WeightT>
167 class LevMarSphere :
public WeightT
175 typedef float ScalarType;
181 template <
class IteratorT>
183 Chi(
const ScalarType* params,
187 ScalarType* temp)
const
190 ScalarType radius = 1 / params[6];
192 Vec3f(params[3], params[4], params[5]);
193 int size = end - begin;
194 #pragma omp parallel for schedule(static) reduction(+ : chi)
195 for (
int idx = 0; idx < size; ++idx)
197 temp[idx] = (begin[idx] -
center).length();
198 chi += (
values[idx] = WeightT::Weigh(temp[idx] - radius)) *
values[idx];
203 template <
class IteratorT>
205 Derivatives(
const ScalarType* params,
209 const ScalarType* temp,
210 ScalarType* matrix)
const
212 Vec3f normal(params[0], params[1], params[2]);
213 Vec3f point(params[3], params[4], params[5]);
214 int size = end - begin;
215 #pragma omp parallel for schedule(static)
216 for (
int idx = 0; idx < size; ++idx)
218 ScalarType denominator = -1.f / temp[idx] * params[6];
219 matrix[idx * NumParams + 0] =
220 (matrix[idx * NumParams + 3] =
221 (point[0] - normal[0] * params[6] - begin[idx][0])) *
223 matrix[idx * NumParams + 1] =
224 (matrix[idx * NumParams + 4] =
225 (point[1] - normal[1] * params[6] - begin[idx][1])) *
227 matrix[idx * NumParams + 2] =
228 (matrix[idx * NumParams + 5] =
229 (point[2] - normal[2] * params[6] - begin[idx][2])) *
231 matrix[idx * NumParams + 3] /= temp[idx];
232 matrix[idx * NumParams + 4] /= temp[idx];
233 matrix[idx * NumParams + 5] /= temp[idx];
234 matrix[idx * NumParams + 6] = (normal[0] * matrix[idx * NumParams + 3] +
235 normal[1] * matrix[idx * NumParams + 4] +
236 normal[2] * matrix[idx * NumParams + 5] + 1) *
237 params[6] * params[6];
238 WeightT::template DerivWeigh<NumParams>(temp[idx] - 1.f / params[6],
239 matrix + idx * NumParams);
244 Normalize(ScalarType* params)
const
247 std::sqrt(params[0] * params[0] + params[1] * params[1] + params[2] * params[2]);
262 return abs((m_center - p).length() - m_radius);
268 *normal = p - m_center;
275 *normal = p - m_center;
276 float l = normal->
length();
281 return abs(l - m_radius);
287 return (m_center - p).length() - m_radius;
290 template <
class IteratorT>
294 LevMarSimpleSphere<LevMarLSWeight> levMarSphere;
296 for (
size_t i = 0; i < 3; ++i)
298 param[i] = m_center[i];
301 if (!
LevMar(begin, end, levMarSphere, param))
305 for (
size_t i = 0; i < 3; ++i)
307 m_center[i] = param[i];
317 Vec3f kDiff = p - m_center;
318 float fA0 = kDiff.
dot(kDiff) - m_radius * m_radius;
319 float fA1, fDiscr, fRoot;
324 fDiscr = fA1 * fA1 - fA0;
325 fRoot =
sqrt(fDiscr);
326 *first = -fA1 + fRoot;
335 fDiscr = fA1 * fA1 - fA0;
340 else if (fDiscr >= 1e-7f)
342 fRoot =
sqrt(fDiscr);
343 *first = -fA1 - fRoot;
344 *second = -fA1 + fRoot;
362 float Parameters(
const Vec3f& p, std::pair<float, float>* param)
const;
363 bool InSpace(
const std::pair<float, float>& param,
bool lower,
Vec3f* p)
const;
364 bool InSpace(
const std::pair<float, float>& param,
bool lower,
Vec3f* p,
Vec3f*
n)
const;
366 void HyperplaneCoordinateSystem(
Vec3f* hcs0,
Vec3f* hcs1,
Vec3f* hcs2)
const;
369 void Hemisphere2Disk(
const Vec3f& p, std::pair<float, float>* inDisk)
const;
370 void Disk2Square(
const std::pair<float, float>& inDisk,
371 std::pair<float, float>* inSquare)
const;
372 void Square2Disk(
const std::pair<float, float>& inSquare,
373 std::pair<float, float>* inDisk)
const;
374 void Disk2Hemisphere(
const std::pair<float, float>& inDisk,
Vec3f* p)
const;