You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
665 lines
24 KiB
665 lines
24 KiB
/**************************************************************************\
|
|
*
|
|
* Copyright (c) 1998 Microsoft Corporation
|
|
*
|
|
* Module Name:
|
|
*
|
|
* Path Self Intersection Remover.
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Classes and functions used to remove self intersections in paths.
|
|
* Given a path, it produces one or more polygons which can be used to
|
|
* draw a widened path that is safe to use alternate fill mode with.
|
|
*
|
|
* Notes:
|
|
*
|
|
* Modified from Office code from John Bowler (at least that is what
|
|
* ericvan told me). Apparently owned by some 'KasiaK', but no idea
|
|
* who that is. (He is apparently retired)
|
|
* CAUTION: Not thoroughly tested yet for arbitrary paths.
|
|
*
|
|
* API:
|
|
* Init(estimatedNumPts);
|
|
* AddPolygon(pathPts, numPts);
|
|
* RemoveSelfIntersects();
|
|
* GetNewPoints(newPts, polyCounts, numPolys, numTotalPts);
|
|
*
|
|
* Created:
|
|
*
|
|
* 06/06/1999 t-wehunt
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifndef _PATH_INTERSECT_REMOVER_H
|
|
#define _PATH_INTERSECT_REMOVER_H
|
|
|
|
|
|
|
|
extern REAL FP_INF;
|
|
|
|
// Forward declarations
|
|
class PathSelfIntersectRemover;
|
|
class Edge;
|
|
|
|
// Comparison function for DynSortArray
|
|
typedef INT (*DynSortArrayCompareFunc)(
|
|
PathSelfIntersectRemover*,
|
|
Edge*,
|
|
Edge*
|
|
);
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
Subtract two points
|
|
*****************************************************************************/
|
|
inline GpPointF SubtractPoint(const GpPointF &pt1, const GpPointF &pt2)
|
|
{
|
|
return GpPointF(pt1.X-pt2.X,pt1.Y-pt2.Y);
|
|
}
|
|
|
|
#ifdef USE_OBSOLETE_DYNSORTARRAY
|
|
|
|
/*****************************************************************************
|
|
DynSortArray
|
|
|
|
Contains a new method that will perform a sorted insertion into the (already
|
|
sorted) array.
|
|
*****************************************************************************/
|
|
|
|
//
|
|
// NOTE: This class should be avoided by all performance critical code.
|
|
// The InsertAt method is O(n) and very easily leads to O(n^3) insert
|
|
// sorting algorithms.
|
|
//
|
|
|
|
template <class T>
|
|
class DynSortArray : public DynArray<T>
|
|
{
|
|
public:
|
|
|
|
// Add a new element to the array at position index.
|
|
// index'th element moves index + 1.
|
|
// CAUTION! could cause a big performance hit if the array is large!
|
|
|
|
GpStatus InsertAt(INT index, const T& newItem)
|
|
{
|
|
return DynArrayImpl::AddMultipleAt(sizeof(T), index, 1, &newItem);
|
|
}
|
|
|
|
// Insert multiple items starting at index'th element.
|
|
// index'th element moves index + n, etc...
|
|
// CAUTION! could cause a big performance hit if the array is large!
|
|
|
|
GpStatus AddMultipleAt(INT index, const T* newItems, INT n)
|
|
{
|
|
return DynArrayImpl::AddMultipleAt(sizeof(T), index, n, newItems);
|
|
}
|
|
|
|
// Another variation of AddMultipleAt above.
|
|
//
|
|
// In this case, the data for the new elements are
|
|
// not available. Instead, we'll do the following:
|
|
// (1) shift the old data over just as AddMultipleAt
|
|
// (2) reserve the space for additional elements
|
|
// (3) increase the Count by the number of additional elements
|
|
// (4) return a pointer to the first new elements
|
|
// CAUTION! could cause a big performance hit if the array is large!
|
|
|
|
T *AddMultipleAt(INT index, INT n)
|
|
{
|
|
return static_cast<T *>(DynArrayImpl::AddMultipleAt(sizeof(T), index, n));
|
|
}
|
|
|
|
// Deletes n items from the array starting at the index'th position.
|
|
// CAUTION! could cause a big performance hit if the array is large!
|
|
|
|
GpStatus DeleteMultipleAt(INT index, INT n)
|
|
{
|
|
return DynArrayImpl::DeleteMultipleAt(sizeof(T), index, n);
|
|
}
|
|
|
|
// Deletes one item from the array at the index'th position.
|
|
// CAUTION! could cause a big performance hit if the array is large!
|
|
|
|
GpStatus DeleteAt(INT index)
|
|
{
|
|
return DynArrayImpl::DeleteMultipleAt(sizeof(T), index, 1);
|
|
}
|
|
|
|
GpStatus InsertSorted(
|
|
T &newItem,
|
|
DynSortArrayCompareFunc compareFunc,
|
|
VOID *userData
|
|
);
|
|
};
|
|
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
Edge
|
|
|
|
Edge represents an edge of a polygon. It stores its end points
|
|
as indices to the array of points.
|
|
|
|
*****************************************************************************/
|
|
|
|
// represents the terminator of the list.
|
|
|
|
#define LIST_END -1
|
|
|
|
|
|
class Edge
|
|
{
|
|
private:
|
|
PathSelfIntersectRemover *Parent;
|
|
Edge() {}
|
|
|
|
public:
|
|
|
|
BOOL CloseReal(const REAL val1, const REAL val2);
|
|
|
|
VOID SetParent(PathSelfIntersectRemover *aParent)
|
|
{
|
|
Parent = aParent;
|
|
}
|
|
|
|
Edge(PathSelfIntersectRemover *aParent)
|
|
{
|
|
SetParent(aParent);
|
|
}
|
|
|
|
// Next pointer. This is an index into the array for the next element
|
|
// in the Edge list. -1 indicates NULL.
|
|
|
|
INT Next;
|
|
|
|
// Begin and End are the indecies to the array of points. The edge
|
|
// has a direction, which is important when we determine winding numbers.
|
|
// Edge goes from Begin to End.
|
|
|
|
INT Begin;
|
|
INT End;
|
|
|
|
// When we look for intersections of edges, we need to sort them based on
|
|
// the smallest x, therefore we want to store the edge, so that SortBegin
|
|
// refers always to the "smaller" end point of this edge.
|
|
INT SortBegin;
|
|
INT SortEnd;
|
|
|
|
// This is the y value at which the edge is currently crossed by a
|
|
// scan line
|
|
REAL YCur;
|
|
|
|
// Original slope of the edge. We want to keep it around even if the
|
|
// is broken up into small pieces and the end points change.
|
|
// We store the slope as the original begin and end points.
|
|
INT OrigBegin;
|
|
INT OrigEnd;
|
|
|
|
// Normalize the edge - ie. update SortBegin and SortEnd.
|
|
VOID Normalize();
|
|
|
|
// Return TRUE if the edge is vertical.
|
|
BOOL IsVertical();
|
|
|
|
VOID MarkOutside();
|
|
};
|
|
|
|
|
|
/*****************************************************************************
|
|
EdgeArray
|
|
|
|
Array of line segments.
|
|
*****************************************************************************/
|
|
typedef DynSortArray<Edge> EdgeArray;
|
|
|
|
/*****************************************************************************
|
|
PointListNode
|
|
|
|
Structure used to maintain the order of points and some additional
|
|
information about them. It is used to create a linked list in an array and
|
|
then to construct final paths.
|
|
Notice the designation List for this structure instead of array.
|
|
*****************************************************************************/
|
|
|
|
struct PointListNode
|
|
{
|
|
INT Prev; // Previous record
|
|
INT Next; // Next record
|
|
|
|
// Duplicate point - For example, if two edges intersect and they are
|
|
// broken up, there are two points needed in order to maintain the
|
|
// correct edge directions for the path. These two points are identical,
|
|
// so we will call them duplicates. Each of them stores an index to the
|
|
// other one. Note that it doesn't mean that allpoints with the same
|
|
// x and y values are duplicates. This is only 1-1 correspondence for
|
|
// points created from intersections.
|
|
INT Dup;
|
|
|
|
// Is this point inside or outside. Actually, this applies to the edge
|
|
// coming out of this point.
|
|
BOOL Inside;
|
|
|
|
// Has this point been consumed during the final creation of resulting
|
|
// paths. Initially set to FALSE and changed to TRUE when the point is
|
|
// copied to the resulting array.
|
|
BOOL Used;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
PathSelfIntersectRemover
|
|
|
|
Path Self Intersection Remover Class.
|
|
|
|
It is given input polygons and returns polygons with all self intersections
|
|
removed. The number of returned polygons can be 1, 2 or more.
|
|
See comments for the methods for more details on input and output arguments.
|
|
|
|
API:
|
|
Init(estimatedNumPts);
|
|
AddPolygon(pathPts, numPts);
|
|
RemoveSelfIntersects();
|
|
GetNewPoints(newPts, polyCounts, numPolys, numTotalPts);
|
|
*****************************************************************************/
|
|
|
|
class PathSelfIntersectRemover
|
|
{
|
|
public:
|
|
|
|
PathSelfIntersectRemover() :
|
|
NumPts(0),
|
|
PathPts(),
|
|
PtList(),
|
|
ActiveVertEdges(),
|
|
ResultPts(),
|
|
CanAddPts(TRUE),
|
|
AddToActive1(NULL),
|
|
AddToActive2(NULL),
|
|
AddToActive3(NULL)
|
|
{
|
|
AddToActive1.SetParent(this);
|
|
AddToActive2.SetParent(this);
|
|
AddToActive3.SetParent(this);
|
|
IntersectsWereRemoved = FALSE;
|
|
}
|
|
|
|
~PathSelfIntersectRemover() {}
|
|
|
|
// Initialize PathSelfIntersectRemover for the given number of points,
|
|
// numPts. numPts can be an approximate number of points that will be
|
|
// added to the PathSelfIntersectRemover class for correction. Init
|
|
// allocates memory for DynArrays.
|
|
|
|
GpStatus Init(INT numPts);
|
|
|
|
// Add one polygon to the class.
|
|
|
|
GpStatus AddPolygon(const GpPointF *ptrPt, INT numPtsToAdd);
|
|
|
|
// Correct the path.
|
|
|
|
GpStatus RemoveSelfIntersects();
|
|
|
|
// Returns the new path. New path contains of 1 or more subpaths
|
|
// The subpaths are stored as a list of points and a list of points
|
|
// per polygon.
|
|
|
|
GpStatus GetNewPoints(DynPointFArray *pts, DynIntArray *polyCounts);
|
|
|
|
BOOL PathWasModified() {return IntersectsWereRemoved;}
|
|
|
|
private:
|
|
|
|
// QuickSort a list of edges from First (F) to Last (L) inclusive.
|
|
// This function uses the CompareLine comparison function to determine
|
|
// the ordering.
|
|
|
|
void QuickSortEdges(Edge *F, Edge *L);
|
|
|
|
// This function moves edges from the list pointed to by pInactiveIndex
|
|
// into the list pointed to by pActiveIndex. The sort order for the Active
|
|
// list is determined by the 'compare' function. Edges are selected from the
|
|
// Inactive list based on xCurrent.
|
|
|
|
void InsertNewEdges(
|
|
INT *pActiveIndex, // IN/OUT
|
|
INT *pInactiveIndex, // IN/OUT
|
|
REAL xCurrent,
|
|
DynSortArrayCompareFunc compare
|
|
);
|
|
|
|
// Delete Edge at index from the list pointed to by pListHead. The edge is
|
|
// orphaned (Next points to LIST_END). This function returns false if
|
|
// index is not present in the list.
|
|
|
|
bool DeleteEdgeFromList(INT *pListHead, INT index);
|
|
|
|
// Insert Edge at index into the list pointed to by pListHead. The sort
|
|
// order is determined by the 'compare' function. The index'th element
|
|
// must be an orphan (not a member of any list) - this
|
|
// function ASSERTs this condition.
|
|
|
|
void InsertEdgeIntoList(
|
|
INT *pListHead,
|
|
INT index,
|
|
DynSortArrayCompareFunc compare
|
|
);
|
|
|
|
// Remove edges from active edge array.
|
|
|
|
void ClearActiveListExclusiveX();
|
|
void ClearActiveListInclusiveX();
|
|
|
|
GpPointF *GetInactivePoint(INT *pInactiveIndex, bool begin);
|
|
|
|
// Return true if two numbers are very close. This depends on the size
|
|
// of the largest number to be compared, which is set in InsertPoints().
|
|
// If no points are inserted, the comparison defaults to using REAL_EPSILON
|
|
|
|
inline BOOL CloseReal(const REAL val1, const REAL val2)
|
|
{
|
|
return (REALABS(val1-val2) < REAL_EPSILON);
|
|
}
|
|
|
|
// Return true if two points are very close
|
|
inline BOOL ClosePt(const GpPointF &pt1, const GpPointF &pt2)
|
|
{
|
|
return (CloseReal(pt1.X, pt2.X) &&
|
|
CloseReal(pt1.Y, pt2.Y));
|
|
}
|
|
|
|
|
|
// Find all intersections between all line segments. Returns FALSE if
|
|
// out of memory
|
|
BOOL FindIntersects();
|
|
|
|
// TODO: Since we have a different function for each phase, we don't need
|
|
// plntFrom any more in both of these methods
|
|
// Add new edges, which are active for the new scan line (x value stored
|
|
// in xCur. ptrFrom - array to get the edges.
|
|
// Returns FALSE on out of memory.
|
|
void AddActiveForX(INT *inactiveHead);
|
|
|
|
// Update duplicate points: the two points overlap, connect their lists
|
|
// of duplicates.
|
|
VOID UpdateDups(INT pt1, INT pt2);
|
|
|
|
BOOL IsLinked(INT loop, INT inew);
|
|
|
|
// Add new edges, which are active for the new scan line (x value stored
|
|
// in xCur. This one is used in the second phase only.
|
|
// Returns FALSE on out of memory.
|
|
void AddActiveForXScan(INT *inactiveHead);
|
|
|
|
|
|
// Find all intersections for the current X value. Intersection points
|
|
// will be inserted into the Edges array and information about their
|
|
// order into PtList.
|
|
// Returns FALSE on out of memory.
|
|
BOOL FindIntersectsForX();
|
|
|
|
// Calculate new current y values for edges in the active edge array.
|
|
// For vertical edges, it will pick the maximum y.
|
|
VOID RecalcActiveYCur();
|
|
|
|
// Eliminate edges/points which are inside. In other words, performes
|
|
// a line sweep algorithm (similar to scan conversion) and calculates
|
|
// winding number on both sides of every edge. If the winding is 0
|
|
// (outside the path) on any sides of the edge, the edge is marked as
|
|
// an outside edge. All other edges are marked as inside. Edges are
|
|
// marked through their begin point in array PtList.
|
|
// Returns FALSE on out of memory.
|
|
BOOL EliminatePoints(VOID);
|
|
|
|
// Finds the x value of the closest end point (in x) - the next scan line.
|
|
// Depending on the phase of the algorithm, it needs to look at edges in
|
|
// different arrays. The new value is stored in xCur.
|
|
// Returns FALSE if there are no more points to look at - we are done.
|
|
BOOL ClosestActive(INT arrayIndex);
|
|
|
|
// Scan through all active edges during the phase of edge elimination.
|
|
// Calculates winding number to the left and to the right of the current
|
|
// x value - xCur. Whenever finds an edge wich has 0 on one side, marks
|
|
// it as an outside edge.
|
|
BOOL ScanActive();
|
|
|
|
// Breaks edge ptrEdge. We have found intersection point intersectPt, which is
|
|
// guranteed to be somewhere on the line segment (not an end point).
|
|
// The 'left' part of the edge will either remain in the active edges
|
|
// or will be removed (only if the intersection point has the current
|
|
// x value. In the latter case, the right edge segment will need to be
|
|
// inserted to active edges, otherwise (the former case) it will go
|
|
// to Pass1Edges. If it needs to go to active edges, Breakedge cannot
|
|
// insert it because it would disrupt the order of edges there before
|
|
// both edges broken up are handled. The caller would have to handle
|
|
// the insertion in such case. Therefore, we return the new line
|
|
// segment newEdge and a BOOL value specifying if the caller has to
|
|
// insert the newEdge edge.
|
|
// dupIndex is the index of the duplicate point created by this
|
|
// intersection:
|
|
// When two edges intersect, we have to insert two points (identical)
|
|
// to maintain the same shape of the polygon. These two points are
|
|
// called duplicates.
|
|
// Return FALSE on out of memory.
|
|
BOOL BreakEdge(
|
|
Edge *ptrEdge,
|
|
GpPointF *intersectPt,
|
|
Edge *newEdge,
|
|
INT dupIndex
|
|
);
|
|
|
|
BOOL BreakEdgeIn3(
|
|
Edge *ptrEdge,
|
|
GpPointF *ptrPt1,
|
|
GpPointF *ptrPt2,
|
|
Edge *ptrNew1,
|
|
Edge *ptrNew2,
|
|
INT dupIndex1,
|
|
INT dupIndex2
|
|
);
|
|
|
|
// Insert numEdges edges joining points stored in array Edges. First
|
|
// point has index firstIndex. There must be numEdges+1 points to
|
|
// create numEdges edges.
|
|
GpStatus InsertEdges(INT firstIndex, INT numEdges);
|
|
|
|
// Insert points information to relevant arrays.
|
|
GpStatus InsertPoints(const GpPointF *pts, INT numPts);
|
|
|
|
// Returns TRUE if lines ptrEdge1 and ptrEdge2 overlap.
|
|
// There are 4 ways in which edges can overlap and depending on the
|
|
// case, either none, one or both edges need to be broken up. In some
|
|
// cases one edge may need to broken into 3 pieces.
|
|
// Return values:
|
|
// split1 - set to TRUE if ptrEdge1 needs to be split
|
|
// split2 - set to TRUE if ptrEdge2 needs to be split
|
|
// split3 - set to TRUE if an edge needs to be broken into 3 pieces
|
|
// intersect1 - intersection point (where edge needs to be split)
|
|
// intersect2 - second point (if edge needs to be broken in 3 pieces or
|
|
// for the second edge if both edges need to broken up)
|
|
// dupIndex1 - index of the duplicate point to intersect1,
|
|
// dupIndex2 - index of the duplicate point to intersect2,
|
|
BOOL Overlap(
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2,
|
|
GpPointF *intersect1,
|
|
GpPointF *intersect2,
|
|
BOOL *split1,
|
|
BOOL *split2,
|
|
BOOL *split3,
|
|
INT *dupIndex1,
|
|
INT *dupIndex2
|
|
);
|
|
|
|
// Method to find the intersection point between edges
|
|
// ptrEdge1 and ptrEdge2.
|
|
// Returns one of the following values:
|
|
// DONOT_INTERS
|
|
// COMMON_POINT
|
|
// INTERSECT
|
|
// COLINEAR
|
|
// If the return value == INTERSECT, intersectPt contains the point of
|
|
// intersection.
|
|
INT IntersectEdge(Edge *ptrEdge1, Edge *ptrEdge2, GpPointF *intersectPt);
|
|
|
|
// IsTIntersection returns TRUE if the intersection point intersectPt is
|
|
// the same as an end point of one of the edges ptrEdge1 and ptrEdge2.
|
|
// If it is, splitFirst will be TRUE if the first edge needs to be broken
|
|
// up (intersectPt is an end point of ptrEdge2), FALSE if the second one
|
|
// needs to be broken up. intersectIndex contains the index of the end
|
|
// point which is the same as the intersection point.
|
|
BOOL IsTIntersection(
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2,
|
|
GpPointF *intersectPt,
|
|
BOOL *splitFirst,
|
|
INT *intersectIndex
|
|
);
|
|
|
|
// Returns TRUE if the two lines ptrEdge1 and ptrEdge2 share a common
|
|
// end point. If they do, commonPt will contain this point.
|
|
BOOL IsCommonPt(Edge *ptrEdge1, Edge *ptrEdge2, GpPointF *commonPt);
|
|
|
|
// After the process of eliminating edges and marking points as inside
|
|
// and outside, we need to go through the linked list of points and
|
|
// build paths from the edges which are outside. CollectPath will
|
|
// collect one path starting from point with index firstIndex.
|
|
// CollectPath doesn't check if firstIndex is marked as Inside or Outside.
|
|
// CollectPath returns FALSE on out of memory
|
|
BOOL CollectPath(INT firstIndex);
|
|
|
|
// Return TRUE if all points have been used (added to the resulting paths)
|
|
// or are inside. If returns FALSE, returns the index to the next unused
|
|
// point
|
|
BOOL AllPointsUsed(INT *nextUnusedPt);
|
|
|
|
// Marks vertical edges as oustide.
|
|
VOID MarkVertOutside();
|
|
|
|
// Remove all vertical edges from the vertical edge array, which do not
|
|
// overlap with the give y value
|
|
VOID RemoveVert(REAL y, BOOL inclusive);
|
|
|
|
VOID RemoveVertAll();
|
|
|
|
// Returns TRUE if edge ptrEdge doesn't belong to the y interval of edges
|
|
// stored in ActiveVertEdges.
|
|
BOOL NewInterval(Edge *ptrEdge);
|
|
|
|
// Delete edges from the active edge table; Indecies of edges to delete
|
|
// are stored in EdgeToDelete1..3. Deletes the highest index edge first.
|
|
// Returns NULL if fails due to out of memory error.
|
|
BOOL DeleteEdges();
|
|
|
|
// Add new edges to the active edge table. The edges are stored in
|
|
// AddToActive1..3. FlgAdd1..3 specify if the given edge needs to
|
|
// be added or not. Returns if fails due to out of memory.
|
|
BOOL AddNewEdges();
|
|
|
|
// Store the edge in PathSelfIntersectRemover for now, so that it can be later added
|
|
// to active edges. Copies the edge, so ptrEdge doesn't need to be kept
|
|
// after this method returns.
|
|
VOID MarkToAdd(Edge *ptrEdge);
|
|
|
|
// Store the edge index for later deletion
|
|
VOID MarkToDelete(INT index);
|
|
|
|
friend INT CompareYCurLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
friend INT
|
|
CompareYScanCurLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
friend INT CompareLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2);
|
|
friend INT CompareVertLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
friend Edge;
|
|
|
|
INT NumPts; // Total #of points stored for corrections
|
|
REAL XCur; // Current x value for the scan line
|
|
DynArray<GpPointF> PathPts; // array of points
|
|
DynArray<GpPointF> ResultPts; // array of points for the resulting paths
|
|
DynArray<PointListNode> PtList; // array with order information for points
|
|
|
|
DynArray<Edge> EdgeList; // List holding all the edges.
|
|
INT ActiveEdgeList; // Head index for the Active Edges
|
|
INT InactiveEdgeList; // Head index for the inactive edges
|
|
|
|
EdgeArray ActiveVertEdges; //array with active vertical edges
|
|
|
|
Edge AddToActive1; //lines which will need to be added to Active edges
|
|
Edge AddToActive2; //these lines are created when edges are broken up
|
|
Edge AddToActive3; //
|
|
|
|
BOOL FlgAdd1; //flags specifying which of the above three lines
|
|
BOOL FlgAdd2; //need to be active
|
|
BOOL FlgAdd3; //
|
|
|
|
INT EdgesToDelete1;//indices of edges, which need to be deleted
|
|
INT EdgesToDelete2;//from active, -1 for all three values means
|
|
INT EdgesToDelete3;//that there are no edges to delete
|
|
|
|
BOOL CanAddPts; // Can we still add new points to the class,
|
|
// We can't after the correction process has started
|
|
|
|
BOOL IntersectsWereRemoved;
|
|
};
|
|
|
|
/*****************************************************************************
|
|
Comparison functions used for array sorting.
|
|
*****************************************************************************/
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Function used to compare lines when we sort them by x coordinate of the
|
|
Begin point (SortBegin - smaller x).
|
|
-------------------------------------------------------------KasiaK---------*/
|
|
INT CompareLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Function used to compare vertical lines when we scan them.
|
|
-------------------------------------------------------------KasiaK---------*/
|
|
INT CompareVertLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Function used to sort edges by current y value when we scan them in order to
|
|
find all intersections of line segments. If y's are the same, sorts based
|
|
on slopes.
|
|
-------------------------------------------------------------KasiaK---------*/
|
|
INT CompareYCurLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Same as CompareYCurLine, but if y-'s are the same, pots left edges before
|
|
right ones before looking at slopes.
|
|
-------------------------------------------------------------KasiaK---------*/
|
|
INT CompareYScanCurLine(
|
|
PathSelfIntersectRemover *ptrCorrector,
|
|
Edge *ptrEdge1,
|
|
Edge *ptrEdge2
|
|
);
|
|
|
|
#endif
|