| 2079 | |
| 2080 | const double a = ( m11 * rhs0 - m01 * rhs1) / det; |
| 2081 | const double b = (-m10 * rhs0 + m00 * rhs1) / det; |
| 2082 | |
| 2083 | return (0 < a) && (a < 1) && (0 < b) && (b < 1) && (0 < a+b) && (a+b < 1); |
| 2084 | } |
| 2085 | |
| 2086 | void trackParabolaCore( std::vector< std::vector<double> > &Cx, std::vector< std::vector<double> > &Cy, |
| 2087 | const double a, const double b, std::vector<double> &x, |
| 2088 | const double *const Vx, const double *const Vy ) |
| 2089 | { |
| 2090 | // y = a * x^2 + b |
| 2091 | std::sort( x.begin(), x.end() ); |
| 2092 | |
| 2093 | // control points: Px[4], Py[4] |
| 2094 | // Bezier curve : P(t) = (1-t)^3 P0 + 3(1-t)^2 t P1 + 3(1-t)t^2 P2 + t^3 P3 |
| 2095 | // = (-P0+3P1-3P2+P3) t^3 + (3P0-6P1+3P2) t^2 + (-3P0+3P1) t + P0 |
| 2096 | // |
| 2097 | // parabola between x0 <= x <= x1 : |
| 2098 | // P(t) = [ (x1-x0)t + x0 ; a*( (x1-x0)t + x0 )^2 + b*( (x1-x0)t + x0 ) + c ] |
| 2099 | // = [ (x1-x0)t + x0 ; a(x1-x0)^2 t^2 + (2*a*x0+b)*(x1-x0) t + (a x_0^2 + bx_0 + c) ] |
| 2100 | // |
| 2101 | // Therefore |
| 2102 | // P0 = [ x0 ; ax_0^2 + bx_0 + c ] |
| 2103 | // -3P0+3P1 = [ x1-x0 ; (2*a*x0+b)*(x1-x0) ] |
| 2104 | // 3P0-6P1+3P2 = [ 0 ; a(x1-x0)^2 ] |
| 2105 | // -P0+3P1-3P2+P3 = [ 0 ; 0 ] |
| 2106 | // <=> |
| 2107 | // P0 = [ x0 ; ax_0^2 + bx_0 + c ] |
| 2108 | // P1 = P0 + [ x1-x0 ; (2*a*x0+b)*(x1-x0) ]/3 |
| 2109 | // P2 = -P0 + 2*P1 + [ 0 ; a(x1-x0)^2 ]/3 |
| 2110 | // P3 = P0-3P1+3P2 |
| 2111 | // From this, P0x = x0, P1x = x0+(x1-x0)/3, P2x = P0x + 2/3*(x1-x0), P3x = x1 |
| 2112 | |
| 2113 | for(int i = 0; i+1 < x.size(); i++){ |
| 2114 | |
| 2115 | const double &X0 = x[i]; |
| 2116 | const double &X1 = x[i+1]; |
| 2117 | const double h = X1 - X0; |
| 2118 | |
| 2119 | const double EPS = 1e-10; |
| 2120 | if( h < EPS) |
| 2121 | continue; |
| 2122 | |
| 2123 | // examine the arc X[i]--X[i+1] is inside triangle or not |
| 2124 | const double mX0 = X0 + h/100; |
| 2125 | const double mY0 = a*mX0*mX0 + b; |
| 2126 | |
| 2127 | const double mX1 = X1 - h/100; |
| 2128 | const double mY1 = a*mX1*mX1 + b; |
| 2129 | if( !(isInsideTriangle( mX0, mY0, Vx, Vy ) && isInsideTriangle( mX1, mY1, Vx, Vy )) ) |
| 2130 | continue; |
| 2131 | |
| 2132 | const double P0y = a*X0*X0 + b; |
| 2133 | const double P1y = P0y + (2*a*X0)*h/3; |
| 2134 | const double P2y = -P0y + 2*P1y + a*h*h/3; |
| 2135 | const double P3y = P0y - 3*P1y + 3*P2y; |
| 2136 | |
| 2137 | Cx.push_back( std::vector<double> { X0, X0+h/3, X1-h/3, X1 } ); |
| 2138 | Cy.push_back( std::vector<double> { P0y, P1y, P2y, P3y } ); |
no test coverage detected