Exemple #1
0
		//------------------------------------------------------------------------------
		
		private void AddGhostJoin(OutPt Op, IntPoint OffPt)
		{
			Join j = new Join();
			j.OutPt1 = Op;
			j.OffPt = OffPt;
			m_GhostJoins.Add(j);
		}
Exemple #2
0
		//------------------------------------------------------------------------------
		
		private bool JoinPoints(Join j, out OutPt p1, out OutPt p2)
		{
			OutRec outRec1 = GetOutRec(j.OutPt1.Idx);
			OutRec outRec2 = GetOutRec(j.OutPt2.Idx);
			OutPt op1 = j.OutPt1, op1b;
			OutPt op2 = j.OutPt2, op2b;
			p1 = null; p2 = null;
			
			//There are 3 kinds of joins for output polygons ...
			//1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere
			//along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
			//2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
			//location at the Bottom of the overlapping segment (& Join.OffPt is above).
			//3. StrictlySimple joins where edges touch but are not collinear and where
			//Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point.
			bool isHorizontal = (j.OutPt1.Pt.Y == j.OffPt.Y);
			
			if (isHorizontal && (j.OffPt == j.OutPt1.Pt) && (j.OffPt == j.OutPt2.Pt))
			{          
				//Strictly Simple join ...
				op1b = j.OutPt1.Next;
				while (op1b != op1 && (op1b.Pt == j.OffPt)) 
					op1b = op1b.Next;
				bool reverse1 = (op1b.Pt.Y > j.OffPt.Y);
				op2b = j.OutPt2.Next;
				while (op2b != op2 && (op2b.Pt == j.OffPt)) 
					op2b = op2b.Next;
				bool reverse2 = (op2b.Pt.Y > j.OffPt.Y);
				if (reverse1 == reverse2) return false;
				if (reverse1)
				{
					op1b = DupOutPt(op1, false);
					op2b = DupOutPt(op2, true);
					op1.Prev = op2;
					op2.Next = op1;
					op1b.Next = op2b;
					op2b.Prev = op1b;
					p1 = op1;
					p2 = op1b;
					return true;
				} else
				{
					op1b = DupOutPt(op1, true);
					op2b = DupOutPt(op2, false);
					op1.Next = op2;
					op2.Prev = op1;
					op1b.Prev = op2b;
					op2b.Next = op1b;
					p1 = op1;
					p2 = op1b;
					return true;
				}
			} 
			else if (isHorizontal)
			{
				//treat horizontal joins differently to non-horizontal joins since with
				//them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
				//may be anywhere along the horizontal edge.
				op1b = op1;
				while (op1.Prev.Pt.Y == op1.Pt.Y && op1.Prev != op1b && op1.Prev != op2)
					op1 = op1.Prev;
				while (op1b.Next.Pt.Y == op1b.Pt.Y && op1b.Next != op1 && op1b.Next != op2)
					op1b = op1b.Next;
				if (op1b.Next == op1 || op1b.Next == op2) return false; //a flat 'polygon'
				
				op2b = op2;
				while (op2.Prev.Pt.Y == op2.Pt.Y && op2.Prev != op2b && op2.Prev != op1b)
					op2 = op2.Prev;
				while (op2b.Next.Pt.Y == op2b.Pt.Y && op2b.Next != op2 && op2b.Next != op1)
					op2b = op2b.Next;
				if (op2b.Next == op2 || op2b.Next == op1) return false; //a flat 'polygon'
				
				cInt Left, Right;
				//Op1 -. Op1b & Op2 -. Op2b are the extremites of the horizontal edges
				if (!GetOverlap(op1.Pt.X, op1b.Pt.X, op2.Pt.X, op2b.Pt.X, out Left, out Right))
					return false;
				
				//DiscardLeftSide: when overlapping edges are joined, a spike will created
				//which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
				//on the discard Side as either may still be needed for other joins ...
				IntPoint Pt;
				bool DiscardLeftSide;
				if (op1.Pt.X >= Left && op1.Pt.X <= Right) 
				{
					Pt = op1.Pt; DiscardLeftSide = (op1.Pt.X > op1b.Pt.X);
				} 
				else if (op2.Pt.X >= Left&& op2.Pt.X <= Right) 
				{
					Pt = op2.Pt; DiscardLeftSide = (op2.Pt.X > op2b.Pt.X);
				} 
				else if (op1b.Pt.X >= Left && op1b.Pt.X <= Right)
				{
					Pt = op1b.Pt; DiscardLeftSide = op1b.Pt.X > op1.Pt.X;
				} 
				else
				{
					Pt = op2b.Pt; DiscardLeftSide = (op2b.Pt.X > op2.Pt.X);
				}
				p1 = op1; p2 = op2;
				return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
			} else
			{
				//nb: For non-horizontal joins ...
				//    1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
				//    2. Jr.OutPt1.Pt > Jr.OffPt.Y
				
				//make sure the polygons are correctly oriented ...
				op1b = op1.Next;
				while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Next;
				bool Reverse1 = ((op1b.Pt.Y > op1.Pt.Y) ||
				                 !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange));
				if (Reverse1)
				{
					op1b = op1.Prev;
					while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Prev;
					if ((op1b.Pt.Y > op1.Pt.Y) ||
					    !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)) return false;
				};
				op2b = op2.Next;
				while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Next;
				bool Reverse2 = ((op2b.Pt.Y > op2.Pt.Y) ||
				                 !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange));
				if (Reverse2)
				{
					op2b = op2.Prev;
					while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Prev;
					if ((op2b.Pt.Y > op2.Pt.Y) ||
					    !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)) return false;
				}
				
				if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
				    ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false;
				
				if (Reverse1)
				{
					op1b = DupOutPt(op1, false);
					op2b = DupOutPt(op2, true);
					op1.Prev = op2;
					op2.Next = op1;
					op1b.Next = op2b;
					op2b.Prev = op1b;
					p1 = op1;
					p2 = op1b;
					return true;
				} else
				{
					op1b = DupOutPt(op1, true);
					op2b = DupOutPt(op2, false);
					op1.Next = op2;
					op2.Prev = op1;
					op1b.Prev = op2b;
					op2b.Next = op1b;
					p1 = op1;
					p2 = op1b;
					return true;
				}
			}
		}
Exemple #3
0
		//------------------------------------------------------------------------------
		
		private void AddJoin(OutPt Op1, OutPt Op2, IntPoint OffPt)
		{
			Join j = new Join();
			j.OutPt1 = Op1;
			j.OutPt2 = Op2;
			j.OffPt = OffPt;
			m_Joins.Add(j);
		}