#include <fitcurve.h>
Public Member Functions | |
CurveFitObject (Path *LongPath, double Error) | |
Constructs a Curve Fitting Object and gives it some data that it will need during the fit. | |
~CurveFitObject () | |
Destroys the curve fitter when it is done, freeing any memory that was allocated in the Initialise() function. | |
BOOL | Initialise (Path *CopyPath, INT32 NumPoints) |
Gets memory to store all the coords in and starts going through the path extracting the relavent points. It also calculates the distance along the path of each of the points it stores, which are needed extensivly when checking the accuracy of the fit. This function also empties the path object ready for the fitted version to be added. | |
void | FitCurve () |
Actually fits the curve and places the results back in the path object declared in the constructor. This function walks through all the data points trying to find cusps in the path and fits curves between them by calling the FitCubic member of the CurveFitObject. | |
Private Member Functions | |
CC_DECLARE_MEMDUMP (CurveFitObject) | |
void | FitCubic (INT32 FirstPoint, INT32 LastPoint, FitPoint Tangent1, FitPoint Tangent2, BOOL IsStartCusp=TRUE, BOOL IsEndCusp=TRUE) |
This function is recursive. It tries to fit a cubic function to the coordinates in the path between FirstPoint and LastPoint. It then compares this function with the actual coordinates to determine how good a fit it has found. If the fit is good it is added to the path object. If the fit is bad then it is split at the point where the fit is at its worst and FitCubic is called again for the left and right halves. Scope: private. | |
void | GenerateBezier (INT32 FirstPoint, INT32 LastPoint, FitPoint Tangent1, FitPoint Tangent2, FitPoint *Bezier) |
This function supplies the maths to try and fit a cubic function to a set of points. It spends its time trying to come up with good lengths for the two tangents passed in to maximise the closeness of the fit. If it fails to come up with realistic results it simply sets the tangent lengths to be 1/3 of the distance between the start point and the end point. Scope: private. | |
FitPoint | BezierPoint (FitPoint *Bez, double u) |
This function simply evaluates the bezier function for a given position and is used to help when determining how good a fit we have obtained Scope: private. | |
double | CalcMaxError (INT32 FirstPoint, INT32 LastPoint, FitPoint *Bezier, INT32 *SplitPoint) |
Finds out how good a fit the bezier curve we have created is when compared with the data points Scope: private. | |
FitPoint | LeftTangent (INT32 Start) |
Finds the Left tangent at the given point in the path Scope: private. | |
FitPoint | RightTangent (INT32 End) |
Finds the Right tangent at the given point in the path Scope: private. | |
FitPoint | CentreTangent (INT32 Centre) |
Finds the tangent at the centre of the path Scope: private. | |
double | Bezier0 (double u) |
double | Bezier1 (double u) |
double | Bezier2 (double u) |
double | Bezier3 (double u) |
void | InsertBezier (FitPoint *Bezier, BOOL, BOOL) |
Adds the bezier curve to the path. If it is that last curve in the fitting (ie Depth is 0) then the rotate flag will not be set Scope: private. | |
void | InsertLine (const DocCoord &Start, const DocCoord &End, FitPoint Tangent1, FitPoint Tangent2, BOOL, BOOL) |
Inserts a straight curve into the path. It keeps it as a curve so that the path will continue to look smooth after it is edited. If this is the last Path element in the fit, (ie Depth is zero) then the rotate flag will not be set. Scope: private. | |
void | InsertStraightLine (const DocCoord &End) |
Inserts a straight Line into the path. This is used in cases where the Line segment must be kept as a straight line (ie by using Straight Line Mode of the FreeHand tool) Scope: private. | |
Private Attributes | |
Path * | LongPath |
DocCoord * | PathArray |
INT32 * | LineArray |
INT32 * | Distances |
double | Error |
INT32 | TotalCoords |
INT32 | TotalStraightLines |
Definition at line 182 of file fitcurve.h.
|
Constructs a Curve Fitting Object and gives it some data that it will need during the fit.
Definition at line 305 of file fitcurve.cpp. 00306 { 00307 // Make a note of info we have got 00308 LongPath = ThePath; 00309 Error = MaxError; 00310 00311 // And set defaults to the rest 00312 Distances = NULL; 00313 PathArray = NULL; 00314 LineArray = NULL; 00315 00316 TotalStraightLines = 0; 00317 TotalCoords = 0; 00318 }
|
|
Destroys the curve fitter when it is done, freeing any memory that was allocated in the Initialise() function.
Definition at line 333 of file fitcurve.cpp. 00334 { 00335 if (Distances!=NULL) 00336 delete Distances; 00337 00338 if (PathArray!=NULL) 00339 delete PathArray; 00340 00341 if (LineArray!=NULL) 00342 delete LineArray; 00343 }
|
|
Definition at line 217 of file fitcurve.h.
|
|
Definition at line 218 of file fitcurve.h.
|
|
Definition at line 219 of file fitcurve.h.
|
|
Definition at line 220 of file fitcurve.h.
|
|
This function simply evaluates the bezier function for a given position and is used to help when determining how good a fit we have obtained Scope: private.
Definition at line 808 of file fitcurve.cpp. 00809 { 00810 double OneMinus = 1.0-u; 00811 double uSquared = u*u; 00812 double OneMinusSquared = OneMinus*OneMinus; 00813 00814 FitPoint Coord; 00815 Coord = Bez[0]*(OneMinusSquared*OneMinus); 00816 Coord = Coord + Bez[1]*(3.0*u*OneMinusSquared); 00817 Coord = Coord + Bez[2]*(3.0*uSquared*OneMinus); 00818 Coord = Coord + Bez[3]*(uSquared*u); 00819 00820 return Coord; 00821 }
|
|
Finds out how good a fit the bezier curve we have created is when compared with the data points Scope: private.
Definition at line 843 of file fitcurve.cpp. 00844 { 00845 double Distance; 00846 double MaxDist = 0.0; 00847 double RTotalLength = 1.0/(Distances[LastPoint] - Distances[FirstPoint]); 00848 FitPoint Point; 00849 00850 // Start out by putting the split point in the middle of the curve segment 00851 INT32 NumPoints = LastPoint - FirstPoint + 1; 00852 *SplitPoint = NumPoints / 2; 00853 INT32 step = (NumPoints+ERROR_STEP) / ERROR_STEP; 00854 00855 // Loop though the points, visiting a fixed number of them 00856 for (INT32 i=FirstPoint+1; i<LastPoint; i+=step) 00857 { 00858 // Calculate the offset at this point 00859 double Offset = Distances[i] - Distances[FirstPoint]; 00860 Offset *= RTotalLength; 00861 00862 // Calculate where the curve actually is and find the distance from where we want it 00863 FitPoint Coord = PathArray[i]; 00864 Point = BezierPoint(Bezier, Offset); 00865 Distance = (Point - Coord).SquaredLength(); 00866 if ( Distance >= MaxDist) 00867 { 00868 MaxDist = Distance; 00869 *SplitPoint = i; 00870 } 00871 } 00872 00873 return MaxDist; 00874 }
|
|
|
|
Finds the tangent at the centre of the path Scope: private.
Definition at line 977 of file fitcurve.cpp. 00978 { 00979 DocCoord Left, Right; 00980 FitPoint CentreTang; 00981 00982 // check for empty point array 00983 if (TotalCoords == 0) 00984 { 00985 CentreTang.x = 1; 00986 CentreTang.y = 0; 00987 00988 return CentreTang; 00989 } 00990 00991 // check for centre outside the array 00992 if ((Centre >= TotalCoords) || (Centre < 0)) 00993 Centre = TotalCoords / 2; 00994 00995 // Find out which point to look to 00996 INT32 Forward = Centre+2; 00997 if (Forward > TotalCoords-1) 00998 Forward = TotalCoords-1; 00999 01000 // Find out which point to look to 01001 INT32 Backward = Centre-2; 01002 if (Backward < 0) 01003 Backward = 0; 01004 01005 // Calc right tangent 01006 Left.x = PathArray[Backward].x - PathArray[Centre].x; 01007 Left.y = PathArray[Backward].y - PathArray[Centre].y; 01008 01009 // Calc left tangent 01010 Right.x = PathArray[Centre].x - PathArray[Forward].x; 01011 Right.y = PathArray[Centre].y - PathArray[Forward].y; 01012 01013 // Average to get the centre tangent 01014 CentreTang.x = (Left.x + Right.x) / 2.0; 01015 CentreTang.y = (Left.y + Right.y) / 2.0; 01016 01017 // Make sure that is not of zero length 01018 if ((CentreTang.x==0) && (CentreTang.y==0)) 01019 { 01020 TRACEALL( _T("Tangent was a zero length vector in the curve fitter (Cent)\n")); 01021 CentreTang.x = 1; 01022 } 01023 01024 // return it 01025 return CentreTang; 01026 }
|
|
This function is recursive. It tries to fit a cubic function to the coordinates in the path between FirstPoint and LastPoint. It then compares this function with the actual coordinates to determine how good a fit it has found. If the fit is good it is added to the path object. If the fit is bad then it is split at the point where the fit is at its worst and FitCubic is called again for the left and right halves. Scope: private.
Definition at line 612 of file fitcurve.cpp. 00614 { 00615 // Will need space for a Bezier curve 00616 FitPoint Bezier[4]; 00617 INT32 NumPoints = LastPoint - FirstPoint + 1; 00618 00619 // if this segment only has 2 points in it then do the special case 00620 if ( NumPoints == 2 ) 00621 { 00622 InsertLine(PathArray[FirstPoint], PathArray[LastPoint], Tangent1, Tangent2, IsStartCusp, IsEndCusp); 00623 return; 00624 } 00625 00626 // Due to a bug in the algorithm we also have to consider 3 points as a special case 00627 if ( NumPoints == 3 ) 00628 { 00629 INT32 Distance = (Distances[LastPoint] - Distances[FirstPoint]) / 3; 00630 00631 // store the end points 00632 Bezier[0] = PathArray[FirstPoint]; 00633 Bezier[3] = PathArray[LastPoint]; 00634 00635 // calc the control points 00636 Bezier[1] = Bezier[0] + Tangent1.SetLength(Distance); 00637 Bezier[2] = Bezier[3] + Tangent2.SetLength(Distance); 00638 00639 // add it to the path 00640 InsertBezier(Bezier, IsStartCusp, IsEndCusp); 00641 return; 00642 } 00643 00644 // Create a Bezier curve from the segemnt and see if it is a good fit 00645 INT32 SplitPoint; 00646 GenerateBezier(FirstPoint, LastPoint, Tangent1, Tangent2, Bezier); 00647 double MaxError = CalcMaxError(FirstPoint, LastPoint, Bezier, &SplitPoint); 00648 00649 if (MaxError < Error) 00650 { 00651 // The mapping was good, so output the curve segment 00652 InsertBezier(Bezier, IsStartCusp, IsEndCusp); 00653 return; 00654 } 00655 00656 // fitting failed -- split at max error point and fit recursively 00657 FitPoint CentTangent = CentreTangent(SplitPoint); 00658 FitCubic(FirstPoint, SplitPoint, Tangent1, CentTangent, IsStartCusp, FALSE); 00659 00660 CentTangent = -CentTangent; 00661 FitCubic(SplitPoint, LastPoint, CentTangent, Tangent2, FALSE, IsEndCusp); 00662 }
|
|
Actually fits the curve and places the results back in the path object declared in the constructor. This function walks through all the data points trying to find cusps in the path and fits curves between them by calling the FitCubic member of the CurveFitObject.
Definition at line 503 of file fitcurve.cpp. 00504 { 00505 FitPoint Tangent1, Tangent2; 00506 double Angle1, Angle2; 00507 INT32 Start = 0; 00508 INT32 StraightLinePos = 0; 00509 00510 for (INT32 i=1; i<TotalCoords-1; i++) 00511 { 00512 if ((TotalStraightLines>0) && (i==LineArray[StraightLinePos])) 00513 { 00514 // if we have a section to the path that needs fitting before we do this then do it 00515 if (Start != (i-1)) 00516 { 00517 // calculate the tangents off the end of the path 00518 Tangent1 = LeftTangent(Start); 00519 Tangent2 = RightTangent(i-1); 00520 00521 // Fit a curve up to the straight line section 00522 FitCubic(Start, i-1, Tangent1, Tangent2); 00523 } 00524 00525 // And draw in the straight line section 00526 InsertStraightLine(PathArray[i]); 00527 StraightLinePos++; 00528 Start = i; 00529 } 00530 else 00531 { 00532 // Go find the angle between a group of points 00533 Angle1 = atan2((double)PathArray[i].y-PathArray[i-1].y, (double)PathArray[i].x-PathArray[i-1].x); 00534 Angle2 = atan2((double)PathArray[i+1].y-PathArray[i].y, (double)PathArray[i+1].x-PathArray[i].x); 00535 00536 // Get them in a sensible range 00537 if (Angle1 < -PI) Angle1 += 2*PI; 00538 if (Angle1 > PI) Angle1 -= 2*PI; 00539 if (Angle2 < -PI) Angle2 += 2*PI; 00540 if (Angle2 > PI) Angle2 -= 2*PI; 00541 00542 // See if this point is a cusp in the curve 00543 if ((fabs(Angle2-Angle1) > (PI/2)) && (fabs(Angle2-Angle1) <= PI)) 00544 { 00545 // calculate the tangents off the end of the path 00546 Tangent1 = LeftTangent(Start); 00547 Tangent2 = RightTangent(i); 00548 00549 // and do a load of maths that will hopefully fit a nice curve on it 00550 FitCubic(Start, i, Tangent1, Tangent2); 00551 Start = i; 00552 } 00553 } 00554 } 00555 00556 00557 INT32 End = TotalCoords-1; 00558 if ((TotalStraightLines>0) && (End==LineArray[StraightLinePos])) 00559 { 00560 // if we have a section to the path that needs fitting before we do this then do it 00561 if (Start != (End-1)) 00562 { 00563 // calculate the tangents off the end of the path 00564 Tangent1 = LeftTangent(Start); 00565 Tangent2 = RightTangent(End-1); 00566 00567 // Fit a curve up to the straight line section 00568 FitCubic(Start, End-1, Tangent1, Tangent2); 00569 } 00570 00571 // And draw in the straight line section 00572 InsertStraightLine(PathArray[End]); 00573 } 00574 else 00575 { 00576 // Just have to fit a curve from the last cusp to the end of the path 00577 Tangent1 = LeftTangent(Start); 00578 Tangent2 = RightTangent(End); 00579 00580 // and do a load of maths that will hopefully fit a nice curve on it 00581 FitCubic(Start, End, Tangent1, Tangent2); 00582 } 00583 }
|
|
This function supplies the maths to try and fit a cubic function to a set of points. It spends its time trying to come up with good lengths for the two tangents passed in to maximise the closeness of the fit. If it fails to come up with realistic results it simply sets the tangent lengths to be 1/3 of the distance between the start point and the end point. Scope: private.
Definition at line 688 of file fitcurve.cpp. 00690 { 00691 INT32 NumPoints = LastPoint - FirstPoint + 1; 00692 00693 // Build a matrix type of thing that contains the tangents scaled by the offsets 00694 FitPoint A[STEP_SIZE+1][2]; // Vector2 (*A)[2] = new Vector2[NumPoints+1][2]; 00695 double Offsets[STEP_SIZE+1]; 00696 00697 INT32 step = (NumPoints+STEP_SIZE) / STEP_SIZE; 00698 INT32 i, pos = 0; 00699 00700 // Chord length parameterisation 00701 const INT32 DistToEnd = Distances[LastPoint] - Distances[FirstPoint]; 00702 for (i=FirstPoint; i<LastPoint+1; i+=step) 00703 { 00704 Offsets[pos] = Distances[i] - Distances[FirstPoint]; 00705 Offsets[pos] /= DistToEnd; 00706 00707 // Fill the matrix A 00708 A[pos][0] = Tangent1.SetLength( Bezier1(Offsets[pos]) ); 00709 A[pos][1] = Tangent2.SetLength( Bezier2(Offsets[pos]) ); 00710 00711 // Move to the next element in the path 00712 pos++; 00713 } 00714 00715 // For a detailed description of the maths used here, please see Graphics Gems I 00716 // I have made some changes to the basic algorithm used there - the main one is 00717 // that this block of maths is only performed on a small selection of the points 00718 // in the data set, where-as the one in the book uses all the points 00719 double C[2][2]; 00720 double X[2]; 00721 00722 C[0][0] = 0.0; 00723 C[0][1] = 0.0; 00724 C[1][0] = 0.0; 00725 C[1][1] = 0.0; 00726 X[0] = 0.0; 00727 X[1] = 0.0; 00728 00729 FitPoint FirstCoord = PathArray[FirstPoint]; 00730 FitPoint LastCoord = PathArray[LastPoint]; 00731 FitPoint ThisCoord, Combo; 00732 00733 pos = 0; 00734 for (i=0; i<NumPoints; i+=step) 00735 { 00736 C[0][0] += A[pos][0].SquaredLength(); 00737 C[0][1] += A[pos][0].Dot(A[pos][1]); 00738 // Point C[1][0] is the same as C[0][1] and is set outside the loop below 00739 C[1][1] += A[pos][1].SquaredLength(); 00740 00741 // Go ahead and build a vector based on the bezier functions 00742 ThisCoord = PathArray[FirstPoint+i]; 00743 Combo = ThisCoord - ((FirstCoord * Bezier0(Offsets[pos])) 00744 + (FirstCoord * Bezier1(Offsets[pos])) 00745 + (LastCoord * Bezier2(Offsets[pos])) 00746 + (LastCoord * Bezier3(Offsets[pos]))); 00747 00748 // Combine it with the other points 00749 X[0] += A[pos][0].Dot( Combo ); 00750 X[1] += A[pos][1].Dot( Combo ); 00751 00752 pos++; 00753 } 00754 00755 // This point in the matrix is the same, so we do not need to do it in the loop 00756 C[1][0] = C[0][1]; 00757 00758 // calc the determinants of C and X 00759 double det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1]; 00760 double det_C0_X = C[0][0] * X[1] - C[0][1] * X[0]; 00761 double det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1]; 00762 00763 // finally, derive the length of the ideal tangents 00764 if (det_C0_C1 == 0.0) 00765 det_C0_C1 = (C[0][0] * C[1][1]) * 10e-12; // oh err, whats it up to here then! 00766 00767 double AlphaLeft = det_X_C1 / det_C0_C1; 00768 double AlphaRight = det_C0_X / det_C0_C1; 00769 00770 Bezier[0] = PathArray[FirstPoint]; 00771 Bezier[3] = PathArray[LastPoint]; 00772 00773 // if alpha negative, the set the tangent length to a third of the distance between 00774 // the start and the end points of the curve segment 00775 if ( AlphaLeft < 0.0 || AlphaRight < 0.0) 00776 { 00777 INT32 Distance = (Distances[LastPoint] - Distances[FirstPoint]) / 3; 00778 00779 Bezier[1] = Bezier[0] + Tangent1.SetLength(Distance); 00780 Bezier[2] = Bezier[3] + Tangent2.SetLength(Distance); 00781 } 00782 else 00783 { 00784 Bezier[1] = Bezier[0] + Tangent1.SetLength(AlphaLeft); 00785 Bezier[2] = Bezier[3] + Tangent2.SetLength(AlphaRight); 00786 } 00787 }
|
|
Gets memory to store all the coords in and starts going through the path extracting the relavent points. It also calculates the distance along the path of each of the points it stores, which are needed extensivly when checking the accuracy of the fit. This function also empties the path object ready for the fitted version to be added.
Definition at line 365 of file fitcurve.cpp. 00366 { 00367 // Here we must try and get some memory for the path array 00368 PathArray = new DocCoord[NumPoints]; 00369 if (PathArray==NULL) 00370 return FALSE; 00371 00372 // copy the data out of the path and into the array. Only copy points of interest 00373 CopyPath->FindStartOfPath(); 00374 DocCoord* Coords = CopyPath->GetCoordArray(); 00375 00376 // Deal with the flags - We have to look for Spare1 being true, meaning that the previous 00377 // Lineto was meant to stay as a straight line 00378 PathFlags* Flags = CopyPath->GetFlagArray(); 00379 TotalStraightLines = 0; 00380 for (INT32 i=0; i<NumPoints; i++) 00381 { 00382 if (Flags[i].Spare1==TRUE) 00383 TotalStraightLines++; 00384 } 00385 00386 // Get some memory to store the positions of the line breaks in 00387 if (TotalStraightLines>0) 00388 { 00389 LineArray = new INT32[TotalStraightLines]; 00390 if (LineArray==NULL) 00391 { 00392 delete PathArray; 00393 PathArray = NULL; 00394 return FALSE; 00395 } 00396 } 00397 00398 // copy the MoveTo out of the path and into our array 00399 PathArray[0].x = Coords[0].x; 00400 PathArray[0].y = Coords[0].y; 00401 00402 INT32 IncludePoint = 1; 00403 INT32 StraightLinePos = 0; 00404 for (INT32 i=1; i<NumPoints; i++) 00405 { 00406 // If this is one of the straight line bits, then make a note of its position 00407 if (Flags[i].Spare1==TRUE) 00408 { 00409 LineArray[StraightLinePos] = IncludePoint; 00410 StraightLinePos++; 00411 } 00412 00413 // Check to see if this coordinate is really needed (last point is always needed) 00414 if ((Coords[i].x != PathArray[IncludePoint-1].x) || (Coords[i].y != PathArray[IncludePoint-1].y) && 00415 (i!=NumPoints-1)) 00416 { 00417 // This point is not the same as the one before, so add it into the array 00418 PathArray[IncludePoint].x = Coords[i].x; 00419 PathArray[IncludePoint].y = Coords[i].y; 00420 00421 IncludePoint++; 00422 } 00423 } 00424 00425 // Add the last point in the track data to the path array if it is not already there 00426 if ((PathArray[IncludePoint-1].x != Coords[NumPoints-1].x) || 00427 (PathArray[IncludePoint-1].y != Coords[NumPoints-1].y)) 00428 { 00429 PathArray[IncludePoint].x = Coords[NumPoints-1].x; 00430 PathArray[IncludePoint].y = Coords[NumPoints-1].y; 00431 IncludePoint++; 00432 } 00433 00434 // increment the Include count (as we have just added a point to the array) and then 00435 // set the true number of points properly. 00436 NumPoints = IncludePoint; 00437 if (NumPoints<2) 00438 { 00439 delete PathArray; 00440 delete LineArray; 00441 PathArray = NULL; 00442 LineArray = NULL; 00443 return FALSE; 00444 } 00445 00446 // Build an array of the distances along the path 00447 Distances = new INT32[NumPoints]; 00448 if (Distances==NULL) 00449 { 00450 delete PathArray; 00451 delete LineArray; 00452 PathArray = NULL; 00453 LineArray = NULL; 00454 return FALSE; 00455 } 00456 00457 Distances[0] = 0; 00458 INT32 dx, dy, min; 00459 for (INT32 i=1; i<NumPoints; i++) 00460 { 00461 // This is doing an approximation to a Square Root 00462 // It is about 250 times faster on a machine without FPU 00463 00464 // find the difference between the last 2 points 00465 dx = abs(PathArray[i].x - PathArray[i-1].x); 00466 dy = abs(PathArray[i].y - PathArray[i-1].y); 00467 00468 // Find out half the smallest of dx and dy 00469 if (dx>dy) 00470 min = dy>>1; 00471 else 00472 min = dx>>1; 00473 00474 Distances[i] = Distances[i-1] + dx + dy - min; 00475 } 00476 00477 // Now we can delete the Path Data in the path we are to put the smoothed path in 00478 LongPath->ClearPath(); 00479 LongPath->FindStartOfPath(); 00480 LongPath->InsertMoveTo(PathArray[0]); 00481 00482 // Store the total number of coords in the array for future reference 00483 TotalCoords = NumPoints; 00484 00485 return TRUE; 00486 }
|
|
Adds the bezier curve to the path. If it is that last curve in the fitting (ie Depth is 0) then the rotate flag will not be set Scope: private.
Definition at line 1045 of file fitcurve.cpp. 01046 { 01047 // Prepare some flags 01048 PathFlags Flags; 01049 Flags.IsSelected = FALSE; 01050 Flags.IsSmooth = FALSE; 01051 Flags.IsRotate = TRUE; 01052 01053 // Add this Bezier curve into the path 01054 LongPath->InsertCurveTo( DocCoord( (INT32)Bezier[1].x, (INT32)Bezier[1].y), 01055 DocCoord( (INT32)Bezier[2].x, (INT32)Bezier[2].y), 01056 DocCoord( (INT32)Bezier[3].x, (INT32)Bezier[3].y), &Flags); 01057 01058 // Deal with cusps 01059 if (IsStartCusp || IsEndCusp) 01060 { 01061 // Go find out about the path 01062 PathFlags* AllFlags = LongPath->GetFlagArray(); 01063 INT32 NumCoords = LongPath->GetNumCoords(); 01064 01065 if (IsStartCusp) 01066 { 01067 // Patch up the flags of the bits near that start 01068 AllFlags[NumCoords-3].IsRotate = FALSE; 01069 } 01070 01071 if (IsEndCusp) 01072 { 01073 // Patch up the flags of the bits near that end 01074 AllFlags[NumCoords-2].IsRotate = FALSE; 01075 AllFlags[NumCoords-1].IsRotate = FALSE; 01076 } 01077 } 01078 }
|
|
Inserts a straight curve into the path. It keeps it as a curve so that the path will continue to look smooth after it is edited. If this is the last Path element in the fit, (ie Depth is zero) then the rotate flag will not be set. Scope: private.
Definition at line 1102 of file fitcurve.cpp. 01104 { 01105 // Prepare some flags 01106 PathFlags Flags; 01107 Flags.IsSelected = FALSE; 01108 Flags.IsSmooth = FALSE; 01109 Flags.IsRotate = TRUE; 01110 01111 // Find out a third of the distance between the two points 01112 FitPoint StartPos(Start); 01113 FitPoint EndPos(End); 01114 FitPoint DistanceVect = EndPos - StartPos; 01115 INT32 Length = (INT32)DistanceVect.Length() / 3; 01116 01117 // Make the tangents the right length 01118 Tangent1 = Tangent1.SetLength(Length); 01119 Tangent2 = Tangent2.SetLength(Length); 01120 01121 // Work out the position of the control points 01122 StartPos = StartPos + Tangent1; 01123 EndPos = EndPos + Tangent2; 01124 01125 // Add the line to the curve 01126 LongPath->InsertCurveTo( DocCoord( (INT32)StartPos.x, (INT32)StartPos.y ), 01127 DocCoord( (INT32)EndPos.x, (INT32)EndPos.y ), 01128 End, &Flags); 01129 01130 // Deal with cusps 01131 if (IsStartCusp || IsEndCusp) 01132 { 01133 // Go find out about the path 01134 PathFlags* AllFlags = LongPath->GetFlagArray(); 01135 INT32 NumCoords = LongPath->GetNumCoords(); 01136 01137 if (IsStartCusp) 01138 { 01139 // Patch up the flags of the bits near that start 01140 AllFlags[NumCoords-3].IsRotate = FALSE; 01141 } 01142 01143 if (IsEndCusp) 01144 { 01145 // Patch up the flags of the bits near that end 01146 AllFlags[NumCoords-2].IsRotate = FALSE; 01147 AllFlags[NumCoords-1].IsRotate = FALSE; 01148 } 01149 } 01150 }
|
|
Inserts a straight Line into the path. This is used in cases where the Line segment must be kept as a straight line (ie by using Straight Line Mode of the FreeHand tool) Scope: private.
Definition at line 1169 of file fitcurve.cpp. 01170 { 01171 // Prepare some flags 01172 PathFlags Flags; 01173 Flags.IsSelected = FALSE; 01174 Flags.IsRotate = FALSE; 01175 Flags.IsSmooth = FALSE; 01176 01177 // Insert the line 01178 LongPath->InsertLineTo(End, &Flags); 01179 }
|
|
Finds the Left tangent at the given point in the path Scope: private.
Definition at line 890 of file fitcurve.cpp. 00891 { 00892 FitPoint Tangent; 00893 00894 // check for empty point array 00895 if (TotalCoords == 0) 00896 { 00897 Tangent.x = 1; 00898 Tangent.y = 0; 00899 00900 return Tangent; 00901 } 00902 00903 // check for start outside the array 00904 if ((Start >= TotalCoords) || (Start < 0)) 00905 Start = TotalCoords / 2; 00906 00907 // Find out which point to look to 00908 INT32 Forward = Start+2; 00909 if (Forward > TotalCoords-1) 00910 Forward = TotalCoords-1; 00911 00912 // Calc the tangent from the left of the curve segment 00913 Tangent.x = PathArray[Forward].x - PathArray[Start].x; 00914 Tangent.y = PathArray[Forward].y - PathArray[Start].y; 00915 00916 // Make sure that is not of zero length 00917 if ((Tangent.x==0) && (Tangent.y==0)) 00918 { 00919 TRACEALL( _T("Tangent was a zero length vector in the curve fitter (left)\n")); 00920 Tangent.x = 1; 00921 } 00922 00923 return Tangent; 00924 }
|
|
Finds the Right tangent at the given point in the path Scope: private.
Definition at line 940 of file fitcurve.cpp. 00941 { 00942 FitPoint Tangent; 00943 00944 // Find out which point to look to 00945 INT32 Backward = End-2; 00946 if (Backward<0) 00947 Backward = 0; 00948 00949 Tangent.x = PathArray[Backward].x - PathArray[End].x; 00950 Tangent.y = PathArray[Backward].y - PathArray[End].y; 00951 00952 // Make sure that is not of zero length 00953 if ((Tangent.x==0) && (Tangent.y==0)) 00954 { 00955 TRACEALL( _T("Tangent was a zero length vector in the curve fitter (Right)\n")); 00956 Tangent.x = -1; 00957 } 00958 00959 return Tangent; 00960 }
|
|
Definition at line 236 of file fitcurve.h. |
|
Definition at line 240 of file fitcurve.h. |
|
Definition at line 233 of file fitcurve.h. |
|
Definition at line 231 of file fitcurve.h. |
|
Definition at line 232 of file fitcurve.h. |
|
Definition at line 243 of file fitcurve.h. |
|
Definition at line 244 of file fitcurve.h. |