22 m_angularRotatedRadians(0)
24 Init(axisDir, axisPos, radius);
30 const Vec3f& normalB) :
31 m_angularRotatedRadians(0)
33 if (!
Init(pointA, pointB, normalA, normalB))
42 if (samples.
size() < 4)
47 m_axisDir =
Vec3f(0, 0, 0);
48 size_t c = samples.
size() / 2;
50 m_axisDir = samples[0 +
c].cross(samples[1 +
c]);
55 m_axisPos =
Vec3f(0, 0, 0);
58 float l = m_axisDir.
dot(samples[0 +
c]);
59 Vec3f xdir = samples[0 +
c] - l * m_axisDir;
64 float lineBnx = ydir.
dot(samples[1 +
c]);
65 if (
abs(lineBnx) < 1e-6)
69 float lineBny = -xdir.
dot(samples[1 +
c]);
71 Vec3f originB = samples[1] - samples[0];
72 float lineBOx = xdir.
dot(originB);
73 float lineBOy = ydir.
dot(originB);
74 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
77 float radius = lineBd / lineBnx;
78 m_axisPos += samples[0] + radius * xdir;
79 m_radius +=
abs(radius);
80 m_radius +=
std::sqrt((radius - lineBOx) * (radius - lineBOx) + lineBOy * lineBOy);
88 float lambda = m_axisDir.dot(-m_axisPos);
89 m_axisPos = m_axisPos + lambda * m_axisDir;
91 m_hcs.FromNormal(m_axisDir);
92 m_angularRotatedRadians = 0;
99 if (samples.
size() < 4)
105 size_t c = samples.
size() / 2;
106 for (
size_t i =
c; i < samples.
size(); ++i)
116 float minEigVal = eigenValues[0];
117 unsigned int minEigIdx = 0;
118 for (
unsigned int i = 1; i < 3; ++i)
119 if (eigenValues[i] < minEigVal)
121 minEigVal = eigenValues[i];
124 m_axisDir =
Vec3f(eigenVectors[minEigIdx]);
126 m_axisPos =
Vec3f(0, 0, 0);
128 size_t pointCount = 0;
129 size_t pairCount = 0;
130 for (
size_t i = 0; i <
c - 1; ++i)
131 for (
size_t j = i + 1; j <
c; ++j)
134 float l = m_axisDir.
dot(samples[i +
c]);
135 Vec3f xdir = samples[i +
c] - l * m_axisDir;
140 float lineBnx = ydir.
dot(samples[j +
c]);
141 if (
abs(lineBnx) < .05f)
145 float lineBny = -xdir.
dot(samples[j +
c]);
147 Vec3f originB = samples[j] - samples[i];
148 float lineBOx = xdir.
dot(originB);
149 float lineBOy = ydir.
dot(originB);
150 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
153 float radius = lineBd / lineBnx;
154 m_axisPos += samples[i] + radius * xdir;
155 m_radius +=
abs(radius);
156 m_radius +=
std::sqrt((radius - lineBOx) * (radius - lineBOx) + lineBOy * lineBOy);
163 m_axisPos /= pointCount;
164 m_radius /= pointCount * 2;
171 float lambda = m_axisDir.
dot(-m_axisPos);
172 m_axisPos = m_axisPos + lambda * m_axisDir;
174 m_hcs.FromNormal(m_axisDir);
175 m_angularRotatedRadians = 0;
185 m_hcs.FromNormal(m_axisDir);
186 m_angularRotatedRadians = 0;
193 if (normalA.
dot(normalB) > 0.9998477)
197 m_axisDir = normalA.
cross(normalB);
205 float lineBnx = planeY.
dot(normalB);
206 float lineBny = -normalA.
dot(normalB);
208 Vec3f originB = pointB - pointA;
209 float lineBOx = normalA.
dot(originB);
210 float lineBOy = planeY.
dot(originB);
211 float lineBd = lineBnx * lineBOx + lineBny * lineBOy;
214 m_radius = lineBd / lineBnx;
215 m_axisPos = pointA + m_radius * normalA;
216 m_radius =
abs(m_radius);
221 m_hcs.FromNormal(m_axisDir);
222 m_angularRotatedRadians = 0;
232 i->read((
char*)&m_axisDir,
sizeof(m_axisDir));
233 i->read((
char*)&m_axisPos,
sizeof(m_axisPos));
234 i->read((
char*)&m_radius,
sizeof(m_radius));
235 i->read((
char*)&rotate,
sizeof(rotate));
239 for (
size_t j = 0; j < 3; ++j)
241 (*i) >> m_axisDir[j];
243 for (
size_t j = 0; j < 3; ++j)
245 (*i) >> m_axisPos[j];
250 m_hcs.FromNormal(m_axisDir);
251 m_angularRotatedRadians = 0;
260 fread(&m_axisDir,
sizeof(m_axisDir), 1, i);
261 fread(&m_axisPos,
sizeof(m_axisPos), 1, i);
262 fread(&m_radius,
sizeof(m_radius), 1, i);
263 fread(&rotate,
sizeof(rotate), 1, i);
264 m_hcs.FromNormal(m_axisDir);
265 m_angularRotatedRadians = 0;
273 for (
int i = 0; i < 3; i++)
275 m_axisDir[i] = array[i];
276 m_axisPos[i] = array[i + 3];
281 m_hcs.FromNormal(m_axisDir);
282 m_angularRotatedRadians = 0;
289 Vec3f diff = m_axisPos - p;
290 float lambda = m_axisDir.
dot(diff);
291 *pp = (diff - lambda * m_axisDir);
293 *pp *= (l - m_radius) / l;
300 Vec3f diff = p - m_axisPos;
301 param->first = m_axisDir.
dot(diff);
302 float planex = diff.
dot(m_hcs[0].Data());
303 float planey = diff.
dot(m_hcs[1].Data());
304 float l = planex * planex + planey * planey;
310 param->second = std::atan2(planey, planex);
311 if (param->second < 0)
356 return Vec3f(m_hcs[0].Data());
363 q.RotationRad(radians, m_axisDir[0], m_axisDir[1], m_axisDir[2]);
368 m_angularRotatedRadians += radians;
375 for (
size_t i = 0; i < 3; ++i)
377 s[i] =
x[i] - param[i];
379 float u = param[5] *
s[1] - param[4] *
s[2];
381 float v = param[3] *
s[2] - param[5] *
s[0];
383 v = param[4] *
s[0] - param[3] *
s[1];
392 for (
size_t i = 0; i < 3; ++i)
394 s[i] =
x[i] - param[i];
396 float g =
s[0] *
x[0] +
s[1] *
x[1] +
s[2] *
x[2];
397 float f = param[5] *
s[1] - param[4] *
s[2];
399 float v = param[3] *
s[2] - param[5] *
s[0];
401 v = param[4] *
s[0] - param[3] *
s[1];
406 gradient[0] =
std::sqrt(1 - param[3] * param[3]);
407 gradient[1] =
std::sqrt(1 - param[4] * param[4]);
408 gradient[2] =
std::sqrt(1 - param[5] * param[5]);
412 gradient[0] = (param[3] * g -
s[0]) / f;
413 gradient[1] = (param[4] * g -
s[1]) / f;
414 gradient[2] = (param[5] * g -
s[2]) / f;
416 gradient[3] = g * gradient[0];
417 gradient[4] = g * gradient[1];
418 gradient[5] = g * gradient[2];
425 float l =
std::sqrt(param[3] * param[3] + param[4] * param[4] + param[5] * param[5]);
426 for (
unsigned int i = 3; i < 6; ++i)
431 float lambda = -(param[0] * param[3] + param[1] * param[4] + param[2] * param[5]);
432 for (
unsigned int i = 0; i < 3; ++i)
434 param[i] = param[i] + lambda * param[i + 3];
453 Vec3f axisPos(0, 0, 0);
454 Vec3f axisDir(0, 0, 0);
456 for (
size_t i = 0; i < cylinders.
size(); ++i)
458 axisPos += weights[i] * cylinders[i].AxisPosition();
459 axisDir += weights[i] * cylinders[i].AxisDirection();
460 r += weights[i] * cylinders[i].Radius();
463 return ic->Init(axisDir, axisPos, r);
471 o->write((
const char*)&m_axisDir,
sizeof(m_axisDir));
472 o->write((
const char*)&m_axisPos,
sizeof(m_axisPos));
473 o->write((
const char*)&m_radius,
sizeof(m_radius));
474 o->write((
const char*)&m_angularRotatedRadians,
sizeof(m_angularRotatedRadians));
478 (*o) << m_axisDir[0] <<
" " << m_axisDir[1] <<
" " << m_axisDir[2] <<
" " << m_axisPos[0]
479 <<
" " << m_axisPos[1] <<
" " << m_axisPos[2] <<
" " << m_radius <<
" "
480 << m_angularRotatedRadians <<
" ";
494 for (
int i = 0; i < 3; i++)
496 array[i] = m_axisDir[i];
497 array[i + 3] = m_axisPos[i];
500 array[7] = m_angularRotatedRadians;
512 fwrite(&m_axisDir,
sizeof(m_axisDir), 1, o);
513 fwrite(&m_axisPos,
sizeof(m_axisPos), 1, o);
514 fwrite(&m_radius,
sizeof(m_radius), 1, o);
515 fwrite(&m_angularRotatedRadians,
sizeof(m_angularRotatedRadians), 1, o);
522 m_axisPos += translate;
531 m_hcs[0] = rot * m_hcs[0];
532 m_hcs[1] = rot * m_hcs[1];