MCPcopy Create free account
hub / github.com/FreeFem/FreeFem-sources / trackParabolaCore

Function trackParabolaCore

plugin/seq/plotPDF.cpp:2081–2136  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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
2086void 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 } );

Callers 1

trackParabolaFunction · 0.85

Calls 5

isInsideTriangleFunction · 0.85
beginMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected