コード例 #1
0
 public static void ApplyMatrix(this Polygons polygons, PointMatrix matrix)
 {
     for (int i = 0; i < polygons.Count; i++)
     {
         for (int j = 0; j < polygons[i].Count; j++)
         {
             polygons[i][j] = matrix.apply(polygons[i][j]);
         }
     }
 }
コード例 #2
0
		public static void ApplyMatrix(this Polygons polygons, PointMatrix matrix)
		{
			for (int i = 0; i < polygons.Count; i++)
			{
				for (int j = 0; j < polygons[i].Count; j++)
				{
					polygons[i][j] = matrix.apply(polygons[i][j]);
				}
			}
		}
コード例 #3
0
        public static bool polygonCollidesWithlineSegment(Polygon poly, IntPoint startPoint, IntPoint endPoint)
        {
            IntPoint diff = endPoint - startPoint;

            PointMatrix transformation_matrix  = new PointMatrix(diff);
            IntPoint    transformed_startPoint = transformation_matrix.apply(startPoint);
            IntPoint    transformed_endPoint   = transformation_matrix.apply(endPoint);

            return(polygonCollidesWithlineSegment(poly, transformed_startPoint, transformed_endPoint, transformation_matrix));
        }
コード例 #4
0
ファイル: infill.cs プロジェクト: larsbrubaker/MatterSlice
        public static void GenerateLinePaths(Polygons polygonToInfill,
                                             Polygons infillLinesToPrint,
                                             long lineSpacing_um,
                                             long infillExtendIntoPerimeter_um,
                                             double rotation,
                                             long rotationOffset = 0,
                                             int speed           = 0)
        {
            if (polygonToInfill.Count > 0)
            {
                Polygons outlines = polygonToInfill.Offset(infillExtendIntoPerimeter_um);
                if (outlines.Count > 0)
                {
                    PointMatrix matrix = new PointMatrix(-(rotation + 90));                     // we are rotating the part so we rotate by the negative so the lines go the way we expect

                    outlines.ApplyMatrix(matrix);

                    Aabb boundary = new Aabb(outlines);

                    boundary.min.X = ((boundary.min.X / lineSpacing_um) - 1) * lineSpacing_um - rotationOffset;
                    int      xLineCount       = (int)((boundary.max.X - boundary.min.X + (lineSpacing_um - 1)) / lineSpacing_um);
                    Polygons unclippedPattern = new Polygons();

                    long firstX = boundary.min.X / lineSpacing_um * lineSpacing_um;
                    for (int lineIndex = 0; lineIndex < xLineCount; lineIndex++)
                    {
                        Polygon line = new Polygon();
                        line.Add(new IntPoint(firstX + lineIndex * lineSpacing_um, boundary.min.Y)
                        {
                            Speed = speed
                        });
                        line.Add(new IntPoint(firstX + lineIndex * lineSpacing_um, boundary.max.Y)
                        {
                            Speed = speed
                        });
                        unclippedPattern.Add(line);
                    }

                    PolyTree ret     = new PolyTree();
                    Clipper  clipper = new Clipper();
                    clipper.AddPaths(unclippedPattern, PolyType.ptSubject, false);
                    clipper.AddPaths(outlines, PolyType.ptClip, true);
                    clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

                    Polygons    newSegments   = Clipper.OpenPathsFromPolyTree(ret);
                    PointMatrix inversematrix = new PointMatrix(rotation + 90);
                    newSegments.ApplyMatrix(inversematrix);

                    infillLinesToPrint.AddRange(newSegments);
                }
            }
        }
コード例 #5
0
ファイル: infill.cs プロジェクト: GearWalker/MatterSlice
		public static void GenerateLinePaths(Polygons polygonToInfill, ref Polygons infillLinesToPrint, int lineSpacing, int infillExtendIntoPerimeter_um, double rotation, long rotationOffset = 0)
		{
			if (polygonToInfill.Count > 0)
			{
				Polygons outlines = polygonToInfill.Offset(infillExtendIntoPerimeter_um);
				if (outlines.Count > 0)
				{
					PointMatrix matrix = new PointMatrix(-(rotation + 90)); // we are rotating the part so we rotate by the negative so the lines go the way we expect

					outlines.ApplyMatrix(matrix);

					Aabb boundary = new Aabb(outlines);

					boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing - rotationOffset;
					int xLineCount = (int)((boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing);
					Polygons unclipedPatern = new Polygons();

					long firstX = boundary.min.X / lineSpacing * lineSpacing;
					for (int lineIndex = 0; lineIndex < xLineCount; lineIndex++)
					{
						Polygon line = new Polygon();
						line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.min.Y));
						line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.max.Y));
						unclipedPatern.Add(line);
					}

					PolyTree ret = new PolyTree();
					Clipper clipper = new Clipper();
					clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
					clipper.AddPaths(outlines, PolyType.ptClip, true);
					clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

					Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret);
					PointMatrix inversematrix = new PointMatrix((rotation + 90));
					newSegments.ApplyMatrix(inversematrix);

					infillLinesToPrint.AddRange(newSegments);
				}
			}
		}
コード例 #6
0
ファイル: infill.cs プロジェクト: iFreeze-Qiu/MatterSlice
        public static void GenerateLinePaths(Polygons in_outline, ref Polygons result, int extrusionWidth_um, int lineSpacing, int infillExtendIntoPerimeter_um, double rotation, long rotationOffset = 0)
        {
            if (in_outline.Count > 0)
            {
                Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um);
                if (outlines.Count > 0)
                {
                    PointMatrix matrix = new PointMatrix(-(rotation + 90)); // we are rotating the part so we rotate by the negative so the lines go the way we expect

                    outlines.applyMatrix(matrix);

                    AABB boundary = new AABB(outlines);

                    boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing - rotationOffset;
                    int      lineCount      = (int)((boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing);
                    Polygons unclipedPatern = new Polygons();
                    long     firstX         = boundary.min.X / lineSpacing * lineSpacing;
                    for (int lineIndex = 0; lineIndex < lineCount; lineIndex++)
                    {
                        Polygon line = new Polygon();
                        line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.min.Y));
                        line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.max.Y));
                        unclipedPatern.Add(line);
                    }

                    PolyTree ret     = new PolyTree();
                    Clipper  clipper = new Clipper();
                    clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
                    clipper.AddPaths(outlines, PolyType.ptClip, true);
                    clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

                    Polygons    newSegments   = Clipper.OpenPathsFromPolyTree(ret);
                    PointMatrix inversematrix = new PointMatrix((rotation + 90));
                    newSegments.applyMatrix(inversematrix);

                    result.AddRange(newSegments);
                }
            }
        }
コード例 #7
0
        bool collisionTest(IntPoint startPoint, IntPoint endPoint)
        {
            IntPoint diff = endPoint - startPoint;

            matrix = new PointMatrix(diff);
            this.nomalizedStartPoint = matrix.apply(startPoint);
            this.normalizedEndPoint  = matrix.apply(endPoint);

            for (int bounderyIndex = 0; bounderyIndex < bounderyPolygons.Count; bounderyIndex++)
            {
                Polygon boundryPolygon = bounderyPolygons[bounderyIndex];
                if (boundryPolygon.Count < 1)
                {
                    continue;
                }

                IntPoint lastPosition = matrix.apply(boundryPolygon[boundryPolygon.Count - 1]);
                for (int pointIndex = 0; pointIndex < boundryPolygon.Count; pointIndex++)
                {
                    IntPoint currentPosition = matrix.apply(boundryPolygon[pointIndex]);
                    if ((lastPosition.Y > nomalizedStartPoint.Y && currentPosition.Y < nomalizedStartPoint.Y) ||
                        (currentPosition.Y > nomalizedStartPoint.Y && lastPosition.Y < nomalizedStartPoint.Y))
                    {
                        long x = lastPosition.X + (currentPosition.X - lastPosition.X) * (nomalizedStartPoint.Y - lastPosition.Y) / (currentPosition.Y - lastPosition.Y);

                        if (x > nomalizedStartPoint.X && x < normalizedEndPoint.X)
                        {
                            return(true);
                        }
                    }

                    lastPosition = currentPosition;
                }
            }
            return(false);
        }
コード例 #8
0
ファイル: infill.cs プロジェクト: wpmyj/AndroidDemo
        public static void GenerateHexLinePaths(Polygons in_outline, ref Polygons result, int lineSpacing, int infillExtendIntoPerimeter_um, double rotationDegrees, int layerIndex)
        {
            int extraRotationAngle = 0;

            if (in_outline.Count > 0)
            {
                Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um);
                if (outlines.Count > 0)
                {
                    int         perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);
                    PointMatrix matrix             = new PointMatrix(-(rotationDegrees + extraRotationAngle));         // we are rotating the part so we rotate by the negative so the lines go the way we expect

                    outlines.ApplyMatrix(matrix);

                    Aabb boundary = new Aabb(outlines);

                    boundary.min.X  = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
                    boundary.min.Y  = ((boundary.min.Y / perIncrementOffset) - 2) * perIncrementOffset;
                    boundary.max.X += lineSpacing;
                    boundary.max.Y += perIncrementOffset;
                    Polygons unclipedPatern = new Polygons();

                    foreach (IntPoint startPoint in StartPositionIterator(boundary, lineSpacing, layerIndex))
                    {
                        Polygon attachedLine = new Polygon();
                        foreach (IntPoint center in IncrementPositionIterator(startPoint, boundary, lineSpacing, layerIndex))
                        {
                            // what we are adding are the little plusses that define the points
                            //        | top
                            //        |
                            //        /\ center
                            //   left/  \ right
                            //
                            IntPoint left  = center + new IntPoint(-lineSpacing / 2, -perIncrementOffset / 3);
                            IntPoint right = center + new IntPoint(lineSpacing / 2, -perIncrementOffset / 3);
                            IntPoint top   = center + new IntPoint(0, perIncrementOffset * 2 / 3);

                            switch (layerIndex % 3)
                            {
                            case 0:                                     // left to right
                                attachedLine.Add(left); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(right);
                                unclipedPatern.Add(new Polygon()
                                {
                                    top, center
                                });
                                break;

                            case 1:                                     // left to top
                                attachedLine.Add(left); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(top);
                                unclipedPatern.Add(new Polygon()
                                {
                                    center, right
                                });
                                break;

                            case 2:                                     // top to right
                                attachedLine.Add(top); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(right);
                                unclipedPatern.Add(new Polygon()
                                {
                                    left, center
                                });
                                break;
                            }
                        }
                        if (attachedLine.Count > 0)
                        {
                            unclipedPatern.Add(attachedLine);
                        }
                    }

                    PolyTree ret     = new PolyTree();
                    Clipper  clipper = new Clipper();
                    clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
                    clipper.AddPaths(outlines, PolyType.ptClip, true);
                    clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

                    Polygons    newSegments   = Clipper.OpenPathsFromPolyTree(ret);
                    PointMatrix inversematrix = new PointMatrix((rotationDegrees + extraRotationAngle));
                    newSegments.ApplyMatrix(inversematrix);

                    result.AddRange(newSegments);
                }
            }
        }
コード例 #9
0
		public static bool polygonCollidesWithlineSegment(Polygons polys, IntPoint startPoint, IntPoint endPoint)
		{
			IntPoint diff = endPoint - startPoint;

			PointMatrix transformation_matrix = new PointMatrix(diff);
			IntPoint transformed_startPoint = transformation_matrix.apply(startPoint);
			IntPoint transformed_endPoint = transformation_matrix.apply(endPoint);

			return polygonCollidesWithlineSegment(polys, transformed_startPoint, transformed_endPoint, transformation_matrix);
		}
コード例 #10
0
		public static bool polygonCollidesWithlineSegment(Polygons polys, IntPoint transformed_startPoint, IntPoint transformed_endPoint, PointMatrix transformation_matrix)
		{
			foreach (Polygon poly in polys)
			{
				if (poly.size() == 0) { continue; }
				if (PolygonHelper.polygonCollidesWithlineSegment(poly, transformed_startPoint, transformed_endPoint, transformation_matrix))
				{
					return true;
				}
			}

			return false;
		}
コード例 #11
0
        public bool CreatePathInsideBoundary(IntPoint startPoint, IntPoint endPoint, List <IntPoint> pathThatIsInside)
        {
            if (saveDebugData)
            {
                using (StreamWriter sw = File.AppendText("test.txt"))
                {
                    if (boundry)
                    {
                        string pointsString = bounderyPolygons.WriteToString();
                        sw.WriteLine(pointsString);
                    }
                    sw.WriteLine(startPoint.ToString() + "  " + endPoint.ToString());
                }
            }

            if ((endPoint - startPoint).ShorterThen(1500))
            {
                // If the movement is very short (not a lot of time to ooze filament)
                // then don't add any points
                return(true);
            }

            bool addEndpoint = false;

            //Check if we are inside the comb boundaries
            if (!PointIsInsideBoundary(startPoint))
            {
                if (!MovePointInsideBoundary(ref startPoint))
                {
                    //If we fail to move the point inside the comb boundary we need to retract.
                    return(false);
                }

                pathThatIsInside.Add(startPoint);
            }

            if (!PointIsInsideBoundary(endPoint))
            {
                if (!MovePointInsideBoundary(ref endPoint))
                {
                    //If we fail to move the point inside the comb boundary we need to retract.
                    return(false);
                }

                addEndpoint = true;
            }

            // Check if we are crossing any bounderies
            if (!DoesLineCrossBoundery(startPoint, endPoint))
            {
                //We're not crossing any boundaries. So skip the comb generation.
                if (!addEndpoint && pathThatIsInside.Count == 0)
                {
                    //Only skip if we didn't move the start and end point.
                    return(true);
                }
            }

            // Calculate the matrix to change points so they are in the direction of the line segment.
            {
                IntPoint diff = endPoint - startPoint;

                lineToSameYMatrix      = new PointMatrix(diff);
                this.rotatedStartPoint = lineToSameYMatrix.apply(startPoint);
                this.rotatedEndPoint   = lineToSameYMatrix.apply(endPoint);
            }


            // Calculate the minimum and maximum positions where we cross the comb boundary
            CalcMinMax();

            long            nomalizedStartX = rotatedStartPoint.X;
            List <IntPoint> pointList       = new List <IntPoint>();

            // Now walk trough the crossings, for every boundary we cross, find the initial cross point and the exit point.
            // Then add all the points in between to the pointList and continue with the next boundary we will cross,
            // until there are no more boundaries to cross.
            // This gives a path from the start to finish curved around the holes that it encounters.
            while (true)
            {
                // if we go up enough we should run into the boundry
                int abovePolyIndex = GetPolygonIndexAbove(nomalizedStartX);
                if (abovePolyIndex < 0)
                {
                    break;
                }

                pointList.Add(lineToSameYMatrix.unapply(new IntPoint(minXPosition[abovePolyIndex] - 200, rotatedStartPoint.Y)));
                if ((indexOfMinX[abovePolyIndex] - indexOfMaxX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count > (indexOfMaxX[abovePolyIndex] - indexOfMinX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count)
                {
                    for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i < bounderyPolygons[abovePolyIndex].Count - 1) ? (i + 1) : (0))
                    {
                        pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i));
                    }
                }
                else
                {
                    indexOfMinX[abovePolyIndex]--;
                    if (indexOfMinX[abovePolyIndex] == -1)
                    {
                        indexOfMinX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1;
                    }

                    indexOfMaxX[abovePolyIndex]--;
                    if (indexOfMaxX[abovePolyIndex] == -1)
                    {
                        indexOfMaxX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1;
                    }

                    for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i > 0) ? (i - 1) : (bounderyPolygons[abovePolyIndex].Count - 1))
                    {
                        pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i));
                    }
                }
                pointList.Add(lineToSameYMatrix.unapply(new IntPoint(maxXPosition[abovePolyIndex] + 200, rotatedStartPoint.Y)));

                nomalizedStartX = maxXPosition[abovePolyIndex];
            }
            pointList.Add(endPoint);

            if (addEndpoint)
            {
                pointList.Add(endPoint);
            }

#if false
            // Optimize the pointList, skip each point we could already reach by connecting directly to the next point.
            for (int startIndex = 0; startIndex < pointList.Count - 2; startIndex++)
            {
                IntPoint startPosition = pointList[startIndex];
                // make sure there is at least one point between the start and the end to optomize
                if (pointList.Count > startIndex + 2)
                {
                    for (int checkIndex = pointList.Count - 1; checkIndex > startIndex + 1; checkIndex--)
                    {
                        IntPoint checkPosition = pointList[checkIndex];
                        if (!DoesLineCrossBoundery(startPosition, checkPosition))
                        {
                            // Remove all the points from startIndex+1 to checkIndex-1, inclusive.
                            for (int i = startIndex + 1; i < checkIndex; i++)
                            {
                                pointList.RemoveAt(startIndex + 1);
                            }

                            // we removed all the points up to start so we are done with the inner loop
                            break;
                        }
                    }
                }
            }
#endif

            foreach (IntPoint point in pointList)
            {
                pathThatIsInside.Add(point);
            }

            return(true);
        }
コード例 #12
0
ファイル: infill.cs プロジェクト: GearWalker/MatterSlice
		public static void GenerateHexLinePaths(Polygons in_outline, ref Polygons result, int lineSpacing, int infillExtendIntoPerimeter_um, double rotationDegrees, int layerIndex)
		{
			int extraRotationAngle = 0;
			if (in_outline.Count > 0)
			{
				Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um);
				if (outlines.Count > 0)
				{
					int perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);
					PointMatrix matrix = new PointMatrix(-(rotationDegrees + extraRotationAngle)); // we are rotating the part so we rotate by the negative so the lines go the way we expect

					outlines.ApplyMatrix(matrix);

					Aabb boundary = new Aabb(outlines);

					boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
					boundary.min.Y = ((boundary.min.Y / perIncrementOffset) - 2) * perIncrementOffset;
					boundary.max.X += lineSpacing;
					boundary.max.Y += perIncrementOffset;
					Polygons unclipedPatern = new Polygons();

					foreach (IntPoint startPoint in StartPositionIterator(boundary, lineSpacing, layerIndex))
					{
						Polygon attachedLine = new Polygon();
						foreach (IntPoint center in IncrementPositionIterator(startPoint, boundary, lineSpacing, layerIndex))
						{
							// what we are adding are the little plusses that define the points
							//        | top
							//        |
							//        /\ center
							//   left/  \ right
							//
							IntPoint left = center + new IntPoint(-lineSpacing / 2, -perIncrementOffset / 3);
							IntPoint right = center + new IntPoint(lineSpacing / 2, -perIncrementOffset / 3);
							IntPoint top = center + new IntPoint(0, perIncrementOffset * 2 / 3);

							switch (layerIndex % 3)
							{
								case 0: // left to right
									attachedLine.Add(left); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(right);
									unclipedPatern.Add(new Polygon() { top, center });
									break;

								case 1: // left to top
									attachedLine.Add(left); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(top);
									unclipedPatern.Add(new Polygon() { center, right });
									break;

								case 2: // top to right
									attachedLine.Add(top); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(right);
									unclipedPatern.Add(new Polygon() { left, center });
									break;
							}
						}
						if (attachedLine.Count > 0)
						{
							unclipedPatern.Add(attachedLine);
						}
					}

					PolyTree ret = new PolyTree();
					Clipper clipper = new Clipper();
					clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
					clipper.AddPaths(outlines, PolyType.ptClip, true);
					clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

					Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret);
					PointMatrix inversematrix = new PointMatrix((rotationDegrees + extraRotationAngle));
					newSegments.ApplyMatrix(inversematrix);

					result.AddRange(newSegments);
				}
			}
		}
コード例 #13
0
        public static bool polygonCollidesWithlineSegment(Polygon poly, IntPoint transformed_startPoint, IntPoint transformed_endPoint, PointMatrix transformation_matrix)
        {
            IntPoint p0 = transformation_matrix.apply(poly.back());

            foreach (IntPoint p1_ in poly)
            {
                IntPoint p1 = transformation_matrix.apply(p1_);
                if ((p0.Y >= transformed_startPoint.Y && p1.Y <= transformed_startPoint.Y) || (p1.Y >= transformed_startPoint.Y && p0.Y <= transformed_startPoint.Y))
                {
                    long x;
                    if (p1.Y == p0.Y)
                    {
                        x = p0.X;
                    }
                    else
                    {
                        x = p0.X + (p1.X - p0.X) * (transformed_startPoint.Y - p0.Y) / (p1.Y - p0.Y);
                    }

                    if (x >= transformed_startPoint.X && x <= transformed_endPoint.X)
                    {
                        return(true);
                    }
                }
                p0 = p1;
            }
            return(false);
        }
コード例 #14
0
		public bool CreatePathInsideBoundary(IntPoint startPoint, IntPoint endPoint, List<IntPoint> pathThatIsInside)
		{
			if (saveDebugData)
			{
				using (StreamWriter sw = File.AppendText("test.txt"))
				{
					if (boundry)
					{
						string pointsString = bounderyPolygons.WriteToString();
						sw.WriteLine(pointsString);
					}
					sw.WriteLine(startPoint.ToString() + "  " + endPoint.ToString());
				}
			}

			if ((endPoint - startPoint).ShorterThen(1500))
			{
				// If the movement is very short (not a lot of time to ooze filament)
				// then don't add any points
				return true;
			}

			bool addEndpoint = false;
			//Check if we are inside the comb boundaries
			if (!PointIsInsideBoundary(startPoint))
			{
				if (!MovePointInsideBoundary(ref startPoint))
				{
					//If we fail to move the point inside the comb boundary we need to retract.
					return false;
				}

				pathThatIsInside.Add(startPoint);
			}

			if (!PointIsInsideBoundary(endPoint))
			{
				if (!MovePointInsideBoundary(ref endPoint))
				{
					//If we fail to move the point inside the comb boundary we need to retract.
					return false;
				}

				addEndpoint = true;
			}

			// Check if we are crossing any bounderies
			if (!DoesLineCrossBoundery(startPoint, endPoint))
			{
				//We're not crossing any boundaries. So skip the comb generation.
				if (!addEndpoint && pathThatIsInside.Count == 0)
				{
					//Only skip if we didn't move the start and end point.
					return true;
				}
			}

			// Calculate the matrix to change points so they are in the direction of the line segment.
			{
				IntPoint diff = endPoint - startPoint;

				lineToSameYMatrix = new PointMatrix(diff);
				this.rotatedStartPoint = lineToSameYMatrix.apply(startPoint);
				this.rotatedEndPoint = lineToSameYMatrix.apply(endPoint);
			}


			// Calculate the minimum and maximum positions where we cross the comb boundary
			CalcMinMax();

			long nomalizedStartX = rotatedStartPoint.X;
			List<IntPoint> pointList = new List<IntPoint>();
			// Now walk trough the crossings, for every boundary we cross, find the initial cross point and the exit point.
			// Then add all the points in between to the pointList and continue with the next boundary we will cross,
			// until there are no more boundaries to cross.
			// This gives a path from the start to finish curved around the holes that it encounters.
			while (true)
			{
				// if we go up enough we should run into the boundry
				int abovePolyIndex = GetPolygonIndexAbove(nomalizedStartX);
				if (abovePolyIndex < 0)
				{
					break;
				}

				pointList.Add(lineToSameYMatrix.unapply(new IntPoint(minXPosition[abovePolyIndex] - 200, rotatedStartPoint.Y)));
				if ((indexOfMinX[abovePolyIndex] - indexOfMaxX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count > (indexOfMaxX[abovePolyIndex] - indexOfMinX[abovePolyIndex] + bounderyPolygons[abovePolyIndex].Count) % bounderyPolygons[abovePolyIndex].Count)
				{
					for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i < bounderyPolygons[abovePolyIndex].Count - 1) ? (i + 1) : (0))
					{
						pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i));
					}
				}
				else
				{
					indexOfMinX[abovePolyIndex]--;
					if (indexOfMinX[abovePolyIndex] == -1)
					{
						indexOfMinX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1;
					}

					indexOfMaxX[abovePolyIndex]--;
					if (indexOfMaxX[abovePolyIndex] == -1)
					{
						indexOfMaxX[abovePolyIndex] = bounderyPolygons[abovePolyIndex].Count - 1;
					}

					for (int i = indexOfMinX[abovePolyIndex]; i != indexOfMaxX[abovePolyIndex]; i = (i > 0) ? (i - 1) : (bounderyPolygons[abovePolyIndex].Count - 1))
					{
						pointList.Add(GetBounderyPointWithOffset(abovePolyIndex, i));
					}
				}
				pointList.Add(lineToSameYMatrix.unapply(new IntPoint(maxXPosition[abovePolyIndex] + 200, rotatedStartPoint.Y)));

				nomalizedStartX = maxXPosition[abovePolyIndex];
			}
			pointList.Add(endPoint);

			if (addEndpoint)
			{
				pointList.Add(endPoint);
			}

#if false
			// Optimize the pointList, skip each point we could already reach by connecting directly to the next point.
			for (int startIndex = 0; startIndex < pointList.Count - 2; startIndex++)
			{
				IntPoint startPosition = pointList[startIndex];
				// make sure there is at least one point between the start and the end to optomize
				if (pointList.Count > startIndex + 2)
				{
					for (int checkIndex = pointList.Count - 1; checkIndex > startIndex + 1; checkIndex--)
					{
						IntPoint checkPosition = pointList[checkIndex];
						if (!DoesLineCrossBoundery(startPosition, checkPosition))
						{
							// Remove all the points from startIndex+1 to checkIndex-1, inclusive.
							for (int i = startIndex + 1; i < checkIndex; i++)
							{
								pointList.RemoveAt(startIndex + 1);
							}

							// we removed all the points up to start so we are done with the inner loop
							break;
						}
					}
				}
			}
#endif

			foreach (IntPoint point in pointList)
			{
				pathThatIsInside.Add(point);
			}

			return true;
		}
コード例 #15
0
        public static bool polygonCollidesWithlineSegment(Polygons polys, IntPoint transformed_startPoint, IntPoint transformed_endPoint, PointMatrix transformation_matrix)
        {
            foreach (Polygon poly in polys)
            {
                if (poly.size() == 0)
                {
                    continue;
                }
                if (PolygonHelper.polygonCollidesWithlineSegment(poly, transformed_startPoint, transformed_endPoint, transformation_matrix))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #16
0
ファイル: PolygonHelper.cs プロジェクト: broettge/MatterSlice
		public static bool polygonCollidesWithlineSegment(Polygon poly, IntPoint transformed_startPoint, IntPoint transformed_endPoint, PointMatrix transformation_matrix)
		{
			IntPoint p0 = transformation_matrix.apply(poly.back());
			foreach (IntPoint p1_ in poly)
			{
				IntPoint p1 = transformation_matrix.apply(p1_);
				if ((p0.Y >= transformed_startPoint.Y && p1.Y <= transformed_startPoint.Y) || (p1.Y >= transformed_startPoint.Y && p0.Y <= transformed_startPoint.Y))
				{
					long x;
					if (p1.Y == p0.Y)
					{
						x = p0.X;
					}
					else
					{
						x = p0.X + (p1.X - p0.X) * (transformed_startPoint.Y - p0.Y) / (p1.Y - p0.Y);
					}

					if (x >= transformed_startPoint.X && x <= transformed_endPoint.X)
						return true;
				}
				p0 = p1;
			}
			return false;
		}