33 #include <visp3/ustk_needle_modeling/usNeedleModelSpline.h>
37 #include <visp3/core/vpException.h>
38 #include <visp3/core/vpMatrix.h>
39 #include <visp3/core/vpRowVector.h>
40 #include <visp3/core/vpTime.h>
45 m_length(0.1), m_outerDiameter(0.001), m_insideDiameter(0), m_needleYoungModulus(200000000000)
53 m_length(needle.m_length), m_outerDiameter(needle.m_outerDiameter), m_insideDiameter(needle.m_insideDiameter),
54 m_needleYoungModulus(needle.m_needleYoungModulus)
207 throw vpException(vpException::badValue,
"usNeedleModelSpline::getNeedlePoint: length out of needle");
215 throw vpException(vpException::badValue,
"usNeedleModelSpline::getNeedleDirection: length out of needle");
221 double threshold)
const
224 throw vpException(vpException::dimensionError,
225 "usNeedleModelSpline::getDistanceFromPoint: invalid point dimension");
234 throw vpException(vpException::badValue,
235 "usNeedleModelSpline::getDistanceFromPoint: invalid start-stop parameters");
237 double middle = (start + stop) / 2;
238 while ((stop - start) > threshold) {
243 if (d0 <= d1 && d0 < d2)
245 else if (d2 < d0 && d2 <= d1)
248 start = (start + middle) / 2;
249 stop = (middle + stop) / 2;
251 middle = (start + stop) / 2;
263 if (
m_spline.front().getOrder() < 2) {
264 for (
unsigned int n = 0; n <
m_spline.size() - 1; n++) {
271 double norm = dX_dl.frobeniusNorm();
272 double curvature = vpColVector::crossProd(dX_dl, dX_dl_2).frobeniusNorm() / pow(norm, 3);
274 E += pow(curvature, 2);
277 for (
unsigned int n = 0; n <
m_spline.size(); n++) {
285 vpColVector Ls_pow(2 * m - 2);
287 vpColVector Le_pow(2 * m - 2);
290 for (
int i = 1; i < 2 * m - 2; i++) {
291 Ls_pow[i] = Ls * Ls_pow[i - 1];
292 Le_pow[i] = Le * Le_pow[i - 1];
297 for (
int i = 2; i <= m; i++) {
298 for (
int j = 2; j <= m; j++) {
299 E += i * (i - 1) * j * (j - 1) / (i + j - 3) * dotProd[i][j] * (Le_pow[i + j - 3] - Ls_pow[i + j - 3]);
319 E *= 0.5 * this->
getEI();
329 double EI = this->
getEI();
331 vpColVector Moment = -EI * vpColVector::crossProd(poly.
getStartTangent(), d2X_dl2);
337 vpColVector Torsor(6);
338 Torsor[0] = Force[0];
339 Torsor[1] = Force[1];
340 Torsor[2] = Force[2];
341 Torsor[3] = Moment[0];
342 Torsor[4] = Moment[1];
343 Torsor[5] = Moment[2];
349 vpColVector &direction3D)
const
365 unsigned int seg = 0;
368 while (L <= start && seg <
m_spline.size()) {
369 L +=
m_spline.at(seg).getParametricLength();
372 int nStart = seg - 1;
374 while (L <= end && seg <
m_spline.size()) {
375 L +=
m_spline.at(seg).getParametricLength();
381 int nbPoints = nEnd - nStart + 1;
388 vpMatrix M(nbPoints, 3);
389 vpRowVector mean(3, 0);
391 for (
int i = 0; i < nbPoints; i++)
392 M.insert(
m_spline.at(nStart + i).getPoint(
m_spline.at(nStart + i).getEndParameter()).t(), i, 0);
394 for (
int i = 0; i < nbPoints; i++)
398 for (
int i = 0; i < nbPoints; i++) {
413 U.resize(nbPoints, 2,
false);
415 S.resize(2, 2,
false);
420 vpColVector d(nbPoints);
421 for (
int i = 0; i < nbPoints; i++) {
422 d[i] = pow(P.t().getCol(i).frobeniusNorm(), 2);
425 vpColVector x(nbPoints, 1);
426 vpMatrix B(nbPoints, 3);
430 vpColVector y = B.pseudoInverse(0) * d;
432 vpColVector center(2);
433 center[0] = y[0] / 2;
434 center[1] = y[1] / 2;
436 double r = sqrt(y[2] + pow(center.frobeniusNorm(), 2));
440 vpColVector cp = P.getRow(0).t() - center;
441 for (
int i = 1; i < nbPoints; i++) {
442 double dot = vpColVector::dotProd(cp, P.getRow(i).t() - center);
447 if (direction3D.size() == 3) {
448 direction3D = V.getCol(2);
449 }
else if (direction3D.size() == 4) {
450 direction3D.insert(0, V.getCol(2));
454 if (center3D.size() == 3) {
455 V.resize(3, 2,
false);
456 center3D = V * center;
457 }
else if (center3D.size() == 4) {
458 V.resize(3, 2,
false);
459 center3D.insert(0, V * center + mean.t());
482 std::cout <<
"Needle " <<
this <<
": " <<
m_spline.size() + 1 <<
" NeedlePoints: \n";
483 for (
unsigned int i = 0; i <
m_spline.size(); i++) {
484 std::cout <<
"\t Point " << i <<
":\n";
485 vpColVector p =
m_spline.at(i).getPoint(
m_spline.at(i).getStartParameter());
486 for (
int j = 0; j < 3; j++) {
487 std::cout <<
"\t\t " << p[j] <<
"\n";
490 std::cout <<
"\t Point " <<
m_spline.size() <<
":\n";
491 vpColVector p =
m_spline.back().getPoint(
m_spline.back().getEndParameter());
492 for (
int j = 0; j < 3; j++) {
493 std::cout <<
"\t\t " << p[j] <<
"\n";
495 std::cout << std::endl;
500 std::cout <<
"Needle " <<
this <<
": " <<
m_spline.size() <<
" NeedleDirections: \n";
501 for (
unsigned int i = 0; i <
m_spline.size(); i++) {
502 std::cout <<
"\t Direction " << i <<
":\n";
503 vpColVector d =
m_spline.at(i).getTangent(
m_spline.at(i).getStartParameter());
504 for (
int j = 0; j < 3; j++) {
505 std::cout <<
"\t\t " << d[j] <<
"\n";
508 std::cout <<
"\t Direction " <<
m_spline.size() <<
":\n";
509 vpColVector d =
m_spline.back().getTangent(
m_spline.back().getEndParameter());
510 for (
int j = 0; j < 3; j++) {
511 std::cout <<
"\t\t " << d[j] <<
"\n";
513 std::cout << std::endl;
518 std::cout <<
"Needle " <<
this <<
": " <<
m_spline.size() <<
" NeedleSegmentCoef: \n";
519 for (
unsigned int i = 0; i <
m_spline.size(); i++) {
520 std::cout <<
"\t Segment " << i <<
":\n";
521 vpMatrix m =
m_spline.at(i).getPolynomialCoefficients();
522 for (
int j = 0; j < 3; j++) {
523 std::cout <<
"\t\t " << std::setw(15) << m[j][0] <<
" " << std::setw(15) << m[j][1] <<
" " << std::setw(15)
524 << m[j][2] <<
" " << std::setw(15) << m[j][3] <<
"\n";
527 std::cout << std::endl;
532 std::cout <<
"Needle " <<
this <<
": " <<
m_spline.size() <<
" NeedleSegmentLength: \n";
533 for (
unsigned int i = 0; i <
m_spline.size(); i++) {
534 std::cout <<
"\t Segment " << i <<
": " <<
m_spline.at(i).getParametricLength() <<
":\n";
536 std::cout << std::endl;
543 s <<
"usNeedleModelSpline\n";
551 for (
int i = 0; i < n; i++)
564 if (c !=
"usNeedleModelSpline") {
565 vpException e(vpException::ioError,
"Stream does not contain usNeedleModelSpline data");
577 for (
int i = 0; i < n; i++)
587 s.write(
"usNeedleModelSpline", 20);
588 s.write((
char *)&(needle.
m_length),
sizeof(
double));
594 s.write((
char *)&n,
sizeof(int));
595 for (
int i = 0; i < n; i++)
608 if (strcmp(c,
"usNeedleModelSpline")) {
609 vpException e(vpException::ioError,
"Stream does not contain usNeedleModelSpline data");
612 s.read((
char *)&(needle.
m_length),
sizeof(
double));
618 s.read((
char *)&n,
sizeof(
int));
621 for (
int i = 0; i < n; i++)
std::vector< usPolynomialCurve3D > m_spline
Polynomials container.
vpColVector getTangent(double param) const
const usBSpline3D & operator=(const usBSpline3D &spline)
vpColVector getPoint(double param) const
Measure curve information.
virtual usNeedleModelBaseTip & operator=(const usNeedleModelBaseTip &needle)
double getDistanceFromPoint(const vpColVector &P, double start=0, double stop=-1, double threshold=1e-5) const
void showNeedleDirections() const
double getFullLength() const
void setFullLength(double length)
Parameters setters and getters.
vpColVector getBaseStaticTorsor() const
Force at base.
vpColVector getNeedleDirection(double l) const
const usNeedleModelSpline & operator=(const usNeedleModelSpline &needle)
double m_length
Needle parameters.
double getInsideDiameter() const
void setNeedleYoungModulus(double E)
void showNeedlePoints() const
Display.
double getCurvatureFromNeedleShape(double start, double end, vpColVector ¢er3D, vpColVector &direction3D) const
Curvature.
virtual ~usNeedleModelSpline()
vpColVector getNeedlePoint(double l) const
Measure model information.
void showNeedleSegmentCoef() const
double m_needleYoungModulus
void init()
Spline definition.
double getOuterDiameter() const
void setInsideDiameter(double diameter)
usNeedleModelSpline()
Constructors, destructor.
double getNeedleYoungModulus() const
void setOuterDiameter(double diameter)
void showNeedleSegmentLength() const
double getBendingEnergy() const
Needle bending.
void loadPreset(const NeedlePreset preset)
Parameters saving and loading.
vpColVector getDerivative(double parameter, unsigned int order) const
vpColVector getStartTangent() const
unsigned int getOrder() const
double getStartParameter() const
void setPolynomialCoefficients(const vpMatrix &polynomialCoefficients)
vpMatrix getPolynomialCoefficients() const
double getEndParameter() const
void setBoundaries(double startParameter, double endParamter)