void nsSMILKeySpline::GetSplineDerivativeValues(double aX, double& aDX, double& aDY) const { double t = GetTForX(aX); aDX = GetSlope(t, mX1, mX2); aDY = GetSlope(t, mY1, mY2); }
Vector* Line::GetIntersection( Line* IntersectsWith ) { float m[2]; float b[2]; m[0] = GetSlope(); m[1] = IntersectsWith->GetSlope(); b[0] = GetIntercept(); b[1] = IntersectsWith->GetIntercept(); float tmp; if( Points[0]->x == Points[1]->x ) { tmp = (m[1] * Points[0]->x) + b[1]; if( (tmp >= Points[0]->y && tmp <= Points[1]->y) || (tmp <= Points[0]->y && tmp >= Points[1]->y) ) return new Vector( Points[0]->x, tmp ); } else if ( IntersectsWith->Points[0]->x == IntersectsWith->Points[1]->x ) { tmp = (m[0] * IntersectsWith->Points[0]->x) + b[0]; if( (tmp >= IntersectsWith->Points[0]->y && tmp <= IntersectsWith->Points[1]->y) || (tmp <= IntersectsWith->Points[0]->y && tmp >= IntersectsWith->Points[1]->y) ) return new Vector( IntersectsWith->Points[0]->x, tmp ); } else { tmp = (b[1] - b[0]) / (m[0] - m[1]); if( tmp >= (Points[0]->x <= Points[1]->x ? Points[0]->x : Points[1]->x) && (Points[0]->x >= Points[1]->x ? Points[0]->x : Points[1]->x) ) if( tmp >= (IntersectsWith->Points[0]->x <= IntersectsWith->Points[1]->x ? IntersectsWith->Points[0]->x : IntersectsWith->Points[1]->x) && (IntersectsWith->Points[0]->x >= IntersectsWith->Points[1]->x ? IntersectsWith->Points[0]->x : IntersectsWith->Points[1]->x) ) return new Vector( tmp, (m[0] * tmp) + b[0] ); } return 0; }
double nsSMILKeySpline::GetTForX(double aX) const { // Find interval where t lies double intervalStart = 0.0; const double* currentSample = &mSampleValues[1]; const double* const lastSample = &mSampleValues[kSplineTableSize - 1]; for (; currentSample != lastSample && *currentSample <= aX; ++currentSample) { intervalStart += kSampleStepSize; } --currentSample; // t now lies between *currentSample and *currentSample+1 // Interpolate to provide an initial guess for t double dist = (aX - *currentSample) / (*(currentSample+1) - *currentSample); double guessForT = intervalStart + dist * kSampleStepSize; // Check the slope to see what strategy to use. If the slope is too small // Newton-Raphson iteration won't converge on a root so we use bisection // instead. double initialSlope = GetSlope(guessForT, mX1, mX2); if (initialSlope >= NEWTON_MIN_SLOPE) { return NewtonRaphsonIterate(aX, guessForT); } else if (initialSlope == 0.0) { return guessForT; } else { return BinarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize); } }
bool LineSegment::ContainsPoint(const Point3D& point) const { Rect rect(p1, p2); if (rect.ContainsPoint(point) == true) { Float slope = CalculateSlope(p1, point); return (Smooth(slope) == Smooth(GetSlope())); } return false; }
Float LineSegment::GetValueAt(Float x) const { if (p1.GetX() != p2.GetX()) { Float slope = GetSlope(); Float intercept = (-1.0 * slope * p1.GetX()) + p1.GetY(); return (slope * x) + intercept; } return 0; }
Point3D LineSegment::GetRandomPoint() const { if (p1.GetX() == p2.GetX()) { Float y = RandomRange(p1.GetY(), p2.GetY()); return Point3D(p1.GetX(), y, 0); } else { Float dx = RandomRange(0, p2.GetX() - p1.GetX()); Float dy = GetSlope() * dx; return Point3D(p1.GetX() + dx, p1.GetY() + dy, 0); } }
double nsSMILKeySpline::NewtonRaphsonIterate(double aX, double aGuessT) const { // Refine guess with Newton-Raphson iteration for (int i = 0; i < NEWTON_ITERATIONS; ++i) { // We're trying to find where f(t) = aX, // so we're actually looking for a root for: CalcBezier(t) - aX double currentX = CalcBezier(aGuessT, mX1, mX2) - aX; double currentSlope = GetSlope(aGuessT, mX1, mX2); if (currentSlope == 0.0) return aGuessT; aGuessT -= currentX / currentSlope; } return aGuessT; }
float Line::GetIntercept() { return Points[0]->y - (GetSlope() * Points[0]->x); }
bool Line::ContainsPoint(const Point3D& point) const { Float slope = CalculateSlope(p1, point); return (Smooth(slope) == Smooth(GetSlope())); }
/********************************************************************** * Function_Name: Interpolate * Return : * Comments : Interpolates from the starting point to the ending point * using the Slope Intercept form. **********************************************************************/ vector<ImagePt> SlopePtLine:: Interpolate(const ImagePt Pt0, const ImagePt Pt1 ) const //(const double ax, const double ay, const double bx, const double by ) { double tempx, tempy; double x0 = Pt0.GetX(); double y0 = Pt0.GetY(); double x1 = Pt1.GetX(); double y1 = Pt1.GetY(); if(x1 < x0) { tempx = x0; x0 = x1; x1 = tempx; tempy = y0; y0 = y1; y1 = tempy; } double slope = GetSlope(Pt0, Pt1); double slope_inv = (double)1/slope; int x = 0; int y = 0; vector<ImagePt> vPt; ImagePt TempPt; TempPt.SetPoint(x0, y0); vPt.push_back(TempPt); if( slope >= 1 ) { // Y Major for( y = y0; y <= y1; y++) { x = x0 + slope_inv * (y - y0); //Frame.SetPixel(x,y, 255, 255, 255); TempPt.SetPoint(x, y); vPt.push_back(TempPt); } } // X Major else if( slope >= 0 && slope < 1) { for(x = x0; x <= x1; x++) { y = y0 + slope * (x - x0); //Frame.SetPixel(x,y, 255, 255, 255); TempPt.SetPoint(x, y); vPt.push_back(TempPt); } } else if( slope < 0 && slope > -1) { for( x = x0; x <= x1; x++) { y = y0 + slope * (x - x0); //Frame.SetPixel(x,y, 255, 255, 255); TempPt.SetPoint(x, y); vPt.push_back(TempPt); } } else if( slope < -1 ) { // Y Major for( y = y0; y >= y1; y--) { x = x0 + slope_inv * (y - y0); //Frame.SetPixel(x,y, 255, 255, 255); TempPt.SetPoint(x, y); vPt.push_back(TempPt); } } return vPt; }