Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcubicbezier.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DVAPI double invCubicBezierX(double x, const TPointD &a, const TPointD &aSpeed,
Shinya Kitaoka 120a6e
                             const TPointD &bSpeed, const TPointD &b) {
Shinya Kitaoka 120a6e
  double aSpeedX            = aSpeed.x;
Shinya Kitaoka 120a6e
  double bSpeedX            = bSpeed.x;
Shinya Kitaoka 120a6e
  if (aSpeedX == 0) aSpeedX = epsilon;
Shinya Kitaoka 120a6e
  if (bSpeedX == 0) bSpeedX = -epsilon;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // a*u^3+b*u^2+c*u+d
Shinya Kitaoka 120a6e
  double x0 = a.x;
Shinya Kitaoka 120a6e
  double x1 = x0 + aSpeedX;
Shinya Kitaoka 120a6e
  double x3 = b.x;
Shinya Kitaoka 120a6e
  double x2 = x3 + bSpeedX;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double aX = x3 + 3 * (x1 - x2) - x0;
Shinya Kitaoka 120a6e
  double bX = 3 * (x2 - 2 * x1 + x0);
Shinya Kitaoka 120a6e
  double cX = 3 * (x1 - x0);
Shinya Kitaoka 120a6e
  double dX = x0 - x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return cubicRoot(aX, bX, cX, dX);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DVAPI double getCubicBezierY(double x, const TPointD &a, const TPointD &aSpeed,
Shinya Kitaoka 120a6e
                             const TPointD &bSpeed, const TPointD &b) {
Shinya Kitaoka 120a6e
  double y0 = a.y;
Shinya Kitaoka 120a6e
  double y1 = y0 + aSpeed.y;
Shinya Kitaoka 120a6e
  double y3 = b.y;
Shinya Kitaoka 120a6e
  double y2 = y3 + bSpeed.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double aY = y3 + 3 * (y1 - y2) - y0;
Shinya Kitaoka 120a6e
  double bY = 3 * (y2 - 2 * y1 + y0);
Shinya Kitaoka 120a6e
  double cY = 3 * (y1 - y0);
Shinya Kitaoka 120a6e
  double dY = y0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double u = invCubicBezierX(x, a, aSpeed, bSpeed, b);
Shinya Kitaoka 120a6e
  u        = tcrop(u, 0.0, 1.0);
Shinya Kitaoka 120a6e
  return aY * u * u * u + bY * u * u + cY * u + dY;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI std::pair<tpointd, tpointd=""> getMinMaxCubicBezierY(const TPointD &a,</tpointd,>
Shinya Kitaoka 120a6e
                                                        const TPointD &aSpeed,
Shinya Kitaoka 120a6e
                                                        const TPointD &bSpeed,
Shinya Kitaoka 120a6e
                                                        const TPointD &b) {
Shinya Kitaoka 120a6e
  double y0 = a.y;
Shinya Kitaoka 120a6e
  double y1 = y0 + aSpeed.y;
Shinya Kitaoka 120a6e
  double y3 = b.y;
Shinya Kitaoka 120a6e
  double y2 = y3 + bSpeed.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double aY = y3 + 3 * (y1 - y2) - y0;
Shinya Kitaoka 120a6e
  double bY = 3 * (y2 - 2 * y1 + y0);
Shinya Kitaoka 120a6e
  double cY = 3 * (y1 - y0);
Shinya Kitaoka 120a6e
  double dY = y0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double x0 = a.x;
Shinya Kitaoka 120a6e
  double x1 = x0 + aSpeed.x;
Shinya Kitaoka 120a6e
  double x3 = b.x;
Shinya Kitaoka 120a6e
  double x2 = x3 + bSpeed.x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double aX = x3 + 3 * (x1 - x2) - x0;
Shinya Kitaoka 120a6e
  double bX = 3 * (x2 - 2 * x1 + x0);
Shinya Kitaoka 120a6e
  double cX = 3 * (x1 - x0);
Shinya Kitaoka 120a6e
  double dX = x0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double aaY = 3 * (y1 - y2) - y0 + y3;
Shinya Kitaoka 120a6e
  double bbY = 2 * (y0 + y2 - 2 * y1);
Shinya Kitaoka 120a6e
  double ccY = y1 - y0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (aaY == 0) {
Shinya Kitaoka 120a6e
    if (a.y < b.y)
Shinya Kitaoka 120a6e
      return std::pair<tpointd, tpointd="">(TPointD(a.x, a.y), TPointD(b.x, b.y));</tpointd,>
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return std::pair<tpointd, tpointd="">(TPointD(b.x, b.y), TPointD(a.x, a.y));</tpointd,>
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    double discr = bbY * bbY - 4 * aaY * ccY;
Shinya Kitaoka 120a6e
    if (discr < 0) {
Shinya Kitaoka 120a6e
      if (a.y < b.y)
Shinya Kitaoka 120a6e
        return std::pair<tpointd, tpointd="">(TPointD(a.x, a.y),</tpointd,>
Shinya Kitaoka 120a6e
                                           TPointD(b.x, b.y));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        return std::pair<tpointd, tpointd="">(TPointD(b.x, b.y),</tpointd,>
Shinya Kitaoka 120a6e
                                           TPointD(a.x, a.y));
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      double sqrt_discr = sqrt(discr);
Shinya Kitaoka 120a6e
      double inv_2aY    = 1.0 / (2.0 * aaY);
Shinya Kitaoka 120a6e
      double u0         = (-bbY + sqrt_discr) * inv_2aY;
Shinya Kitaoka 120a6e
      double u1         = (-bbY - sqrt_discr) * inv_2aY;
Shinya Kitaoka 120a6e
      if (u0 > 1.0) u0  = 1.0;
Shinya Kitaoka 120a6e
      if (u0 < 0.0) u0  = 0.0;
Shinya Kitaoka 120a6e
      if (u1 > 1.0) u1  = 1.0;
Shinya Kitaoka 120a6e
      if (u1 < 0.0) u1  = 0.0;
Shinya Kitaoka 120a6e
      double y_0        = aY * u0 * u0 * u0 + bY * u0 * u0 + cY * u0 + dY;
Shinya Kitaoka 120a6e
      double y_1        = aY * u1 * u1 * u1 + bY * u1 * u1 + cY * u1 + dY;
Shinya Kitaoka 120a6e
      double x_0        = aX * u0 * u0 * u0 + bX * u0 * u0 + cX * u0 + dX;
Shinya Kitaoka 120a6e
      double x_1        = aX * u1 * u1 * u1 + bX * u1 * u1 + cX * u1 + dX;
Shinya Kitaoka 120a6e
      if (y_0 < y_1)
Shinya Kitaoka 120a6e
        return std::pair<tpointd, tpointd="">(TPointD(x_0, y_0),</tpointd,>
Shinya Kitaoka 120a6e
                                           TPointD(x_1, y_1));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        return std::pair<tpointd, tpointd="">(TPointD(x_1, y_1),</tpointd,>
Shinya Kitaoka 120a6e
                                           TPointD(x_0, y_0));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------