14 :
std::runtime_error(
"Parallel normals")
18 : m_angularRotatedRadians(0)
22 : m_angularRotatedRadians(0)
24 Init(axisDir, axisPos, radius);
29 : m_angularRotatedRadians(0)
31 if (!
Init(pointA, pointB, normalA, normalB))
39 if (samples.
size() < 4)
44 m_axisDir =
Vec3f(0, 0, 0);
45 size_t c = samples.
size() / 2;
47 m_axisDir = samples[0 +
c].cross(samples[1 +
c]);
52 m_axisPos =
Vec3f(0, 0, 0);
55 float l = m_axisDir.
dot(samples[0 +
c]);
56 Vec3f xdir = samples[0 +
c] - l * m_axisDir;
61 float lineBnx = ydir.
dot(samples[1 +
c]);
62 if (
abs(lineBnx) < 1e-6)
66 float lineBny = -xdir.
dot(samples[1 +
c]);
68 Vec3f originB = samples[1] - samples[0];
69 float lineBOx = xdir.
dot(originB);
70 float lineBOy = ydir.
dot(originB);
71 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
74 float radius = lineBd / lineBnx;
75 m_axisPos += samples[0] + radius * xdir;
76 m_radius +=
abs(radius);
77 m_radius +=
std::sqrt((radius - lineBOx) * (radius - lineBOx) + lineBOy * lineBOy);
85 float lambda = m_axisDir.dot(-m_axisPos);
86 m_axisPos = m_axisPos + lambda * m_axisDir;
88 m_hcs.FromNormal(m_axisDir);
89 m_angularRotatedRadians = 0;
95 if (samples.
size() < 4)
101 size_t c = samples.
size() / 2;
102 for (
size_t i =
c; i < samples.
size(); ++i)
110 normals.
begin(), normals.
end(), &cov);
113 float minEigVal = eigenValues[0];
114 unsigned int minEigIdx = 0;
115 for (
unsigned int i = 1; i < 3; ++i)
116 if (eigenValues[i] < minEigVal)
118 minEigVal = eigenValues[i];
121 m_axisDir =
Vec3f(eigenVectors[minEigIdx]);
123 m_axisPos =
Vec3f(0, 0, 0);
125 size_t pointCount = 0;
126 size_t pairCount = 0;
127 for (
size_t i = 0; i <
c - 1; ++i)
128 for (
size_t j = i + 1; j <
c; ++j)
131 float l = m_axisDir.
dot(samples[i +
c]);
132 Vec3f xdir = samples[i +
c] - l * m_axisDir;
137 float lineBnx = ydir.
dot(samples[j +
c]);
138 if (
abs(lineBnx) < .05f)
142 float lineBny = -xdir.
dot(samples[j +
c]);
144 Vec3f originB = samples[j] - samples[i];
145 float lineBOx = xdir.
dot(originB);
146 float lineBOy = ydir.
dot(originB);
147 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
150 float radius = lineBd / lineBnx;
151 m_axisPos += samples[i] + radius * xdir;
152 m_radius +=
abs(radius);
153 m_radius +=
std::sqrt((radius - lineBOx) * (radius - lineBOx) + lineBOy * lineBOy);
160 m_axisPos /= pointCount;
161 m_radius /= pointCount * 2;
168 float lambda = m_axisDir.
dot(-m_axisPos);
169 m_axisPos = m_axisPos + lambda * m_axisDir;
171 m_hcs.FromNormal(m_axisDir);
172 m_angularRotatedRadians = 0;
181 m_hcs.FromNormal(m_axisDir);
182 m_angularRotatedRadians = 0;
189 if (normalA.
dot(normalB) > 0.9998477)
193 m_axisDir = normalA.
cross(normalB);
201 float lineBnx = planeY.
dot(normalB);
202 float lineBny = -normalA.
dot(normalB);
204 Vec3f originB = pointB - pointA;
205 float lineBOx = normalA.
dot(originB);
206 float lineBOy = planeY.
dot(originB);
207 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
210 m_radius = lineBd / lineBnx;
211 m_axisPos = pointA + m_radius * normalA;
212 m_radius =
abs(m_radius);
217 m_hcs.FromNormal(m_axisDir);
218 m_angularRotatedRadians = 0;
227 i->read((
char*)&m_axisDir,
sizeof(m_axisDir));
228 i->read((
char*)&m_axisPos,
sizeof(m_axisPos));
229 i->read((
char*)&m_radius,
sizeof(m_radius));
230 i->read((
char*)&rotate,
sizeof(rotate));
234 for (
size_t j = 0; j < 3; ++j)
236 (*i) >> m_axisDir[j];
238 for (
size_t j = 0; j < 3; ++j)
240 (*i) >> m_axisPos[j];
245 m_hcs.FromNormal(m_axisDir);
246 m_angularRotatedRadians = 0;
254 fread(&m_axisDir,
sizeof(m_axisDir), 1, i);
255 fread(&m_axisPos,
sizeof(m_axisPos), 1, i);
256 fread(&m_radius,
sizeof(m_radius), 1, i);
257 fread(&rotate,
sizeof(rotate), 1, i);
258 m_hcs.FromNormal(m_axisDir);
259 m_angularRotatedRadians = 0;
266 for (
int i = 0; i < 3; i++)
268 m_axisDir[i] = array[i];
269 m_axisPos[i] = array[i + 3];
274 m_hcs.FromNormal(m_axisDir);
275 m_angularRotatedRadians = 0;
281 Vec3f diff = m_axisPos - p;
282 float lambda = m_axisDir.
dot(diff);
283 *pp = (diff - lambda * m_axisDir);
285 *pp *= (l - m_radius) / l;
290 std::pair< float, float >* param)
const
292 Vec3f diff = p - m_axisPos;
293 param->first = m_axisDir.
dot(diff);
294 float planex = diff.
dot(m_hcs[0].Data());
295 float planey = diff.
dot(m_hcs[1].Data());
296 float l = planex * planex + planey * planey;
302 param->second = std::atan2(planey, planex);
303 if (param->second < 0)
341 return Vec3f(m_hcs[0].Data());
347 q.RotationRad(radians, m_axisDir[0], m_axisDir[1], m_axisDir[2]);
352 m_angularRotatedRadians += radians;
358 for (
size_t i = 0; i < 3; ++i)
360 s[i] = x[i] - param[i];
362 float u = param[5] *
s[1] - param[4] *
s[2];
364 float v = param[3] *
s[2] - param[5] *
s[0];
366 v = param[4] *
s[0] - param[3] *
s[1];
375 for (
size_t i = 0; i < 3; ++i)
377 s[i] = x[i] - param[i];
379 float g =
s[0] * x[0] +
s[1] * x[1] +
s[2] * x[2];
380 float f = param[5] *
s[1] - param[4] *
s[2];
382 float v = param[3] *
s[2] - param[5] *
s[0];
384 v = param[4] *
s[0] - param[3] *
s[1];
389 gradient[0] =
std::sqrt(1 - param[3] * param[3]);
390 gradient[1] =
std::sqrt(1 - param[4] * param[4]);
391 gradient[2] =
std::sqrt(1 - param[5] * param[5]);
395 gradient[0] = (param[3] * g -
s[0]) / f;
396 gradient[1] = (param[4] * g -
s[1]) / f;
397 gradient[2] = (param[5] * g -
s[2]) / f;
399 gradient[3] = g * gradient[0];
400 gradient[4] = g * gradient[1];
401 gradient[5] = g * gradient[2];
407 float l =
std::sqrt(param[3] * param[3] + param[4] * param[4]
408 + param[5] * param[5]);
409 for (
unsigned int i = 3; i < 6; ++i)
414 float lambda = -(param[0] * param[3] + param[1] * param[4] +
415 param[2] * param[5]);
416 for (
unsigned int i = 0; i < 3; ++i)
418 param[i] = param[i] + lambda * param[i + 3];
434 Vec3f axisPos(0, 0, 0);
435 Vec3f axisDir(0, 0, 0);
437 for (
size_t i = 0; i < cylinders.
size(); ++i)
439 axisPos += weights[i] * cylinders[i].AxisPosition();
440 axisDir += weights[i] * cylinders[i].AxisDirection();
441 r += weights[i] * cylinders[i].Radius();
444 return ic->Init(axisDir, axisPos, r);
451 o->write((
const char*)&m_axisDir,
sizeof(m_axisDir));
452 o->write((
const char*)&m_axisPos,
sizeof(m_axisPos));
453 o->write((
const char*)&m_radius,
sizeof(m_radius));
454 o->write((
const char*)&m_angularRotatedRadians,
455 sizeof(m_angularRotatedRadians));
459 (*o) << m_axisDir[0] <<
" " << m_axisDir[1] <<
" " << m_axisDir[2] <<
" "
460 << m_axisPos[0] <<
" " << m_axisPos[1] <<
" " << m_axisPos[2] <<
" "
461 << m_radius <<
" " << m_angularRotatedRadians <<
" ";
476 for (
int i = 0; i < 3; i++)
478 array[i] = m_axisDir[i];
479 array[i + 3] = m_axisPos[i];
482 array[7] = m_angularRotatedRadians;
492 fwrite(&m_axisDir,
sizeof(m_axisDir), 1, o);
493 fwrite(&m_axisPos,
sizeof(m_axisPos), 1, o);
494 fwrite(&m_radius,
sizeof(m_radius), 1, o);
495 fwrite(&m_angularRotatedRadians,
496 sizeof(m_angularRotatedRadians), 1, o);
502 m_axisPos += translate;
511 m_hcs[0] = rot * m_hcs[0];
512 m_hcs[1] = rot * m_hcs[1];