public Population(int populationSize, Boolean initialise, Paths pgs, IntPoint m_startPoint,Tour greedtour)
        {
            this.oripaths = pgs;   //保存传入的路劲集合,用来计算适应度,及距离
            this.startPoint = m_startPoint;

            tours = new Tour[populationSize];        //种群路劲集合

            int greedseedsize = 15;
            // If we need to initialise a population of tours do so
            if (initialise)
            {
                for (int j = 0; j < greedseedsize; j++)
                {
                    saveTour(j, greedtour);
                }

                // Loop and create individuals
                for (int i = greedseedsize; i < populationSize; i++)
                {
                    Tour newTour = new Tour(pgs.Count);
                    newTour.generateIndividual();
                    saveTour(i, newTour);
                }
            }
        }
Beispiel #2
0
    public static int GetMask(Vector2i p)
    {
        int mask = 0;

        if (p.x == currentLowerPoint.x)
        {
            mask = mask | 1;
        }

        if (p.x == currentUpperPoint.x)
        {
            mask = mask | 2;
        }

        if (p.y == currentLowerPoint.y)
        {
            mask = mask | 4;
        }

        if (p.y == currentUpperPoint.y)
        {
            mask = mask | 8;
        }

        return(mask);
    }
 private static Vector2 ConvertToFloatingPoint(ClipperLib.IntPoint p, Box2 range)
 {
     return(new Vector2
            (
                ConvertToFloatingPoint(p.X, range.XRange),
                ConvertToFloatingPoint(p.Y, range.YRange)
            ));
 }
 public static Vector2f ToVector2f(this Vector2i p)
 {
     return(new Vector2f
     {
         x = (float)(p.x / float2int64),
         y = (float)(p.y / float2int64)
     });
 }
Beispiel #5
0
    public static bool PointNotLieOnEdges(Vector2i p)
    {
        //return p.x != currentLowerPoint.x && p.x != currentUpperPoint.x
        //    && p.y != currentLowerPoint.y && p.y != currentUpperPoint.y;

        return(p.x - currentLowerPoint.x - epsilon > 0 && p.y - currentLowerPoint.y - epsilon > 0 &&
               currentUpperPoint.x - p.x - epsilon > 0 && currentUpperPoint.y - p.y - epsilon > 0);
    }
 public static Vector3 ToVector3f(this Vector2i p)
 {
     return(new Vector3
     {
         x = (float)(p.x / float2int64),
         y = (float)(p.y / float2int64),
         z = 0f
     });
 }
Beispiel #7
0
        public static bool pointInPolygon(SvgPoint point, NFP polygon)
        {
            // scaling is deliberately coarse to filter out points that lie *on* the polygon

            var p  = svgToClipper2(polygon, 1000);
            var pt = new ClipperLib.IntPoint(1000 * point.x, 1000 * point.y);

            return(ClipperLib.Clipper.PointInPolygon(pt, p.ToList()) > 0);
        }
		public PointMatrix(IntPoint p)
		{
			matrix[0] = p.X;
			matrix[1] = p.Y;
			double f = Sqrt((matrix[0] * matrix[0]) + (matrix[1] * matrix[1]));
			matrix[0] /= f;
			matrix[1] /= f;
			matrix[2] = -matrix[1];
			matrix[3] = matrix[0];
		}
		public static void ApplyTranslation(this Polygons polygons, IntPoint translation)
		{
			for (int i = 0; i < polygons.Count; i++)
			{
				for (int j = 0; j < polygons[i].Count; j++)
				{
					polygons[i][j] = polygons[i][j] + translation;
				}
			}
		}
        public Line(Vector2i p1, Vector2i p2)
        {
            Vector2i d = new Vector2i {
                x = p2.x - p1.x, y = p2.y - p1.y
            };
            float m = Mathf.Sqrt(d.x * d.x + d.y * d.y);

            a     = -d.y / m;
            b     = d.x / m;
            c     = -(a * p1.x + b * p1.y);
            angle = 0f;
        }
    void BuildVertices(Vector2 center)
    {
        vertices.Clear();
        for (int i = 0; i < segmentCount; i++)
        {
            float angle = Mathf.Deg2Rad * (-90f - 360f / segmentCount * i);

            Vector2  point     = new Vector2(center.x + radius * Mathf.Cos(angle), center.y + radius * Mathf.Sin(angle));
            Vector2i point_i64 = point.ToVector2i();
            vertices.Add(point_i64);
        }
    }
Beispiel #12
0
        public static bool GetPoint(Vector2[] quad, bool outter, out List<Vector2> list, bool isClose=true)
        {
            List<IntPoint> quadLines = new List<IntPoint>();
            for(int i=0; i < quad.Length; i++){
                Vector3 from = quad[i];
                IntPoint to = new IntPoint(from.x * DrawHelper.ClipScalling, from.y * DrawHelper.ClipScalling);
                quadLines.Add(to);

                //				IntPoint to = quad[i+1];
                //				to = new IntPoint(to.X * scale.X * scalling, to.Y * scale.Y * scalling);
                //				quadLines.Add(to);
            }

            EndType endType = EndType.etOpenButt;
            if(isClose){
                endType = EndType.etClosedPolygon;
            }

            //Debug.Log("endType: " + endType);

            ClipperOffset co = new ClipperOffset();
            co.AddPath(quadLines, JoinType.jtMiter, endType);
            Paths solution = new Paths();
            double delta = -DrawHelper.WallThick/2 * DrawHelper.ClipScalling;
            if(outter){
                delta = -delta;
            }

            co.MiterLimit = 8;
            co.Execute(ref solution, delta);

            list = new List<Vector2>();

            if(solution.Count > 0){
                foreach(IntPoint p in solution[0]){
                    Vector3 re = new Vector3(p.X * 1.0f/DrawHelper.ClipScalling, p.Y * 1.0f/DrawHelper.ClipScalling, 0f);

                    if(!isClose){
                        //Debug.Log("result: " + re);
                    }

                    list.Add(re);
                }
                list.Add(list[0]);
                return Clipper.Orientation(solution[0]);
            }
            else{
                Debug.LogError("no solution..");
            }

            return true;
        }
Beispiel #13
0
        public static bool IsVertexConcave(this Polygon vertices, int vertex)
        {
            IntPoint current = vertices[vertex];
            IntPoint next = vertices[(vertex + 1) % vertices.Count];
            IntPoint previous = vertices[vertex == 0 ? vertices.Count - 1 : vertex - 1];

            IntPoint left = new IntPoint(current.X - previous.X, current.Y - previous.Y);
            IntPoint right = new IntPoint(next.X - current.X, next.Y - current.Y);

            long cross = (left.X * right.Y) - (left.Y * right.X);

            return cross < 0;
        }
		public void InsideOutsidePoints()
		{
			{
				// a square with a hole (outside is ccw inside is cw)
				// __________
				// | _____  |
				// | |    | |
				// | |____| |
				// |________|
				string partOutlineString = "x:0, y:0,x:1000, y:0,x:1000, y:1000,x:0, y:1000,|x:100, y:100,x:0, y:900,x:900, y:900,x:900, y:0,|";
				Polygons bounderyPolygons = PolygonsHelper.CreateFromString(partOutlineString);
				AvoidCrossingPerimeters testHarness = new AvoidCrossingPerimeters(bounderyPolygons);
				Assert.IsTrue(testHarness.PointIsInsideBoundary(new IntPoint(1, 1)));
			}

			// Here is a test case that was failing.
			{
				// Looks a little like this
				// _____
				// |   |
				// | O |
				// | O |
				// |___|

				string partOutlineString = "x:90501, y:80501,x:109500, y:80501,x:109500, y:119500,x:90501, y:119500,|x:97387, y:104041,x:95594, y:105213,x:94278, y:106903,x:93583, y:108929,x:93583, y:111071,x:94278, y:113097,x:95594, y:114787,x:97387, y:115959,x:99464, y:116485,x:101598, y:116307,x:103559, y:115447,x:105135, y:113996,x:106154, y:112113,x:106507, y:110000,x:106154, y:107887,x:105135, y:106004,x:103559, y:104553,x:101598, y:103693,x:99464, y:103515,|x:97387, y:84042,x:95594, y:85214,x:94278, y:86904,x:93583, y:88930,x:93583, y:91072,x:94278, y:93098,x:95594, y:94788,x:97387, y:95960,x:99464, y:96486,x:101598, y:96308,x:103559, y:95448,x:105135, y:93997,x:106154, y:92114,x:106507, y:90001,x:106154, y:87888,x:105135, y:86005,x:103559, y:84554,x:101598, y:83694,x:99464, y:83516,|";
				Polygons bounderyPolygons = PolygonsHelper.CreateFromString(partOutlineString);
				IntPoint startPoint = new IntPoint(95765, 114600);
				IntPoint endPoint = new IntPoint(99485, 96234);
				AvoidCrossingPerimeters testHarness = new AvoidCrossingPerimeters(bounderyPolygons);

				{
					IntPoint startPointInside = startPoint;
					testHarness.MovePointInsideBoundary(ref startPointInside);
					IntPoint endPointInside = endPoint;
					testHarness.MovePointInsideBoundary(ref endPointInside);

					Assert.IsTrue(testHarness.PointIsInsideBoundary(startPointInside));
					Assert.IsTrue(testHarness.PointIsInsideBoundary(endPointInside));

					Polygon insidePath = new Polygon();
					testHarness.CreatePathInsideBoundary(startPointInside, endPointInside, insidePath);
					Assert.IsTrue(insidePath.Count > 10); // It needs to go around the cicle so it needs many points (2 is a definate fail).
				}

				{
					Polygon insidePath = new Polygon();
					testHarness.CreatePathInsideBoundary(startPoint, endPoint, insidePath);
					Assert.IsTrue(insidePath.Count > 12); // two more than the last test to get the points in the right place
				}
			}
		}
    public List <Vector2i> GetVertices()
    {
        List <Vector2i> vertices = new List <Vector2i>();

        for (int i = 0; i < segmentCount; i++)
        {
            float angle = Mathf.Deg2Rad * (-90f - 360f / segmentCount * i);

            Vector2  point     = new Vector2(clipPosition.x + radius * Mathf.Cos(angle), clipPosition.y + radius * Mathf.Sin(angle));
            Vector2i point_i64 = point.ToVector2i();
            vertices.Add(point_i64);
        }
        return(vertices);
    }
    public void Clip(TurningChisel chisel)
    {
        if (polygon == null)
        {
            return;
        }

        List <Polygon> solution = new List <Polygon>();

        ClipperLib.Clipper clipper = new ClipperLib.Clipper();
        clipper.AddPolygon(polygon, ClipperLib.PolyType.ptSubject);
        clipper.AddPolygon(chisel.Polygon, ClipperLib.PolyType.ptClip);
        clipper.Execute(ClipperLib.ClipType.ctDifference, solution, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero);

        polygon = null;
        if (solution.Count > 0)
        {
            Vector2i basePosition = transform.localPosition.ToVector2i();

            polygon = null;
            for (int i = 0; i < solution.Count; i++)
            {
                var   poly = solution[i];
                float xA   = (float)(poly[1].X - basePosition.X);
                float xB   = (float)(poly[poly.Count - 2].X - basePosition.Y);

                if (xA * xB < 0f)
                {
                    polygon = poly;
                }
                else
                {
                    StartCoroutine(CreateDetachedObject(poly));
                }
            }
        }

        if (polygon != null)
        {
            ExtractEdge();
            PostShapeChange();
        }
        else
        {
            polygon = null;
            ExtractEdge();
            PostShapeChange();
        }
    }
Beispiel #17
0
        public static bool Inside(IList<IntPoint> polygon, IntPoint position, bool toleranceOnOutside = true)
        {
            IntPoint point = position;

            const float epsilon = 0.5f;

            bool inside = false;

            // Must have 3 or more edges
            if (polygon.Count < 3) return false;

            IntPoint oldPoint = polygon[polygon.Count - 1];
            float oldSqDist = (oldPoint - point).LengthSquared();

            for (int i = 0; i < polygon.Count; i++)
            {
                IntPoint newPoint = polygon[i];
                float newSqDist = (newPoint - point).LengthSquared();

                if (oldSqDist + newSqDist + 2.0f * System.Math.Sqrt(oldSqDist * newSqDist) - (newPoint - oldPoint).LengthSquared() < epsilon)
                {
                    return toleranceOnOutside;
                }

                IntPoint left;
                IntPoint right;
                if (newPoint.X > oldPoint.X)
                {
                    left = oldPoint;
                    right = newPoint;
                }
                else
                {
                    left = newPoint;
                    right = oldPoint;
                }

                if (left.X < point.X && point.X <= right.X && (point.Y - left.Y) * (right.X - left.X) < (right.Y - left.Y) * (point.X - left.X))
                {
                    inside = !inside;
                }

                oldPoint = newPoint;
                oldSqDist = newSqDist;
            }

            return inside;
        }
Beispiel #18
0
		public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance_um)
		{
			this.gcodeExport = gcode;
			travelConfig = new GCodePathConfig(travelSpeed, 0, "travel");

			LastPosition = gcode.GetPositionXY();
			outerPerimetersToAvoidCrossing = null;
			extrudeSpeedFactor = 100;
			travelSpeedFactor = 100;
			extraTime = 0.0;
			totalPrintTime = 0.0;
			forceRetraction = false;
			alwaysRetract = false;
			currentExtruderIndex = gcode.GetExtruderIndex();
			this.retractionMinimumDistance_um = retractionMinimumDistance_um;
		}
        public static List<Vector2> Add(this Shape shape, Shape secondShape, Action<Shape> completed)
        {
            List<Vector2> points = new List<Vector2>();

            Clipper c = new Clipper();

            List<List<IntPoint>> subj = new List<List<IntPoint>>();
            List<List<IntPoint>> clip = new List<List<IntPoint>>();
            List<List<IntPoint>> solution = new List<List<IntPoint>>();
            List<IntPoint> p1 = new List<IntPoint>();
            List<IntPoint> p2 = new List<IntPoint>();
            int i = 0, l = shape.Points.Length;
            Vector2 pos = shape.BuiltGameObject.transform.position;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(shape.Points[i].x + pos.x,shape.Points[i].y + pos.y);
                p1.Add(ip);
            }
            p1.Add(p1[0]);

            pos = secondShape.BuiltGameObject.transform.position;
            i = 0; l = secondShape.Points.Length;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(secondShape.Points[i].x + pos.x,secondShape.Points[i].y + pos.y);
                p2.Add(ip);
            }
            p2.Add(p2[0]);

            subj.Add(p1);
            clip.Add(p2);

            c.AddPaths(subj,PolyType.ptSubject,true);
            c.AddPaths(clip,PolyType.ptClip,true);
            c.Execute(ClipType.ctUnion,solution);

            i = 0; l = solution[0].Count;
            for(;i<l;++i)
            {
                float x = System.Convert.ToSingle(solution[0][i].X);
                float y = System.Convert.ToSingle(solution[0][i].Y);
                points.Add(new Vector2(x,y));
            }

            Mesh2D.Instance.ReBuild(shape.BuiltGameObject,points,completed,shape.Col);
            return points;
        }
Beispiel #20
0
        //------------------------------------------------------------------------------
        public void AddPath(List<IntPoint> path, JoinType joinType, EndType endType)
        {
            int highI = path.Count - 1;
            if (highI < 0) return;
            PolyNode newNode = new PolyNode();
            newNode.m_jointype = joinType;
            newNode.m_endtype = endType;

            //strip duplicate points from path and also get index to the lowest point ...
            if (endType == EndType.etClosedLine || endType == EndType.etClosedPolygon)
                while (highI > 0 && path[0] == path[highI]) highI--;
            newNode.m_polygon.Capacity = highI + 1;
            newNode.m_polygon.Add(path[0]);
            int j = 0, k = 0;
            for (int i = 1; i <= highI; i++)
                if (newNode.m_polygon[j] != path[i])
                {
                    j++;
                    newNode.m_polygon.Add(path[i]);
                    if (path[i].Y > newNode.m_polygon[k].Y ||
                      (path[i].Y == newNode.m_polygon[k].Y &&
                      path[i].X < newNode.m_polygon[k].X)) k = j;
                }
            if (endType == EndType.etClosedPolygon && j < 2) return;

            m_polyNodes.AddChild(newNode);

            //if this path's lowest pt is lower than all the others then update m_lowest
            if (endType != EndType.etClosedPolygon) return;
            if (m_lowest.X < 0)
                m_lowest = new IntPoint(m_polyNodes.ChildCount - 1, k);
            else
            {
                IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X].m_polygon[(int)m_lowest.Y];
                if (newNode.m_polygon[k].Y > ip.Y ||
                  (newNode.m_polygon[k].Y == ip.Y &&
                  newNode.m_polygon[k].X < ip.X))
                    m_lowest = new IntPoint(m_polyNodes.ChildCount - 1, k);
            }
        }
    void BuildVertices(Vector2 begin, Vector2 end)
    {
        vertices.Clear();
        int halfSegmentCount = segmentCount / 2;

        touchLine = new TouchLineOverlapCheck(begin, end);

        for (int i = 0; i <= halfSegmentCount; i++)
        {
            float    angle     = Mathf.Deg2Rad * (touchLine.angle + 270f - (float)360f / segmentCount * i);
            Vector2  point     = new Vector2(begin.x + radius * Mathf.Cos(angle), begin.y + radius * Mathf.Sin(angle));
            Vector2i point_i64 = point.ToVector2i();
            vertices.Add(point_i64);
        }

        for (int i = halfSegmentCount; i <= segmentCount; i++)
        {
            float    angle     = Mathf.Deg2Rad * (touchLine.angle + 270f - (float)360f / segmentCount * i);
            Vector2  point     = new Vector2(end.x + radius * Mathf.Cos(angle), end.y + radius * Mathf.Sin(angle));
            Vector2i point_i64 = point.ToVector2i();
            vertices.Add(point_i64);
        }
    }
Beispiel #22
0
 public bool IsOutside(Vector2 point)
 {
     var p = new IntPoint(point.X, point.Y);
     return Clipper.PointInPolygon(p, ToClipperPath()) != 1;
 }
		public static bool PointInPolygon(Polygon polygon, IntPoint testPosition)
		{
			int numPoints = polygon.Count;
			bool result = false;
			for (int i = 0; i < numPoints; i++)
			{
				int prevIndex = i - 1;
				if (prevIndex < 0)
				{
					prevIndex += numPoints;
				}

				if ((((polygon[i].Y <= testPosition.Y) && (testPosition.Y < polygon[prevIndex].Y))
					|| ((polygon[prevIndex].Y <= testPosition.Y) && (testPosition.Y < polygon[i].Y)))
					&& (testPosition.X - polygon[i].X < (polygon[prevIndex].X - polygon[i].X) * (testPosition.Y - polygon[i].Y) / (polygon[prevIndex].Y - polygon[i].Y)))
				{
					result = !result;
				}
			}

			return result;
		}
        //------------------------------------------------------------------------------
        private void BuildIntersectList(Int64 botY, Int64 topY)
        {
            if ( m_ActiveEdges == null ) return;

              //prepare for sorting ...
              TEdge e = m_ActiveEdges;
              e.tmpX = TopX( e, topY );
              m_SortedEdges = e;
              m_SortedEdges.prevInSEL = null;
              e = e.nextInAEL;
              while( e != null )
              {
            e.prevInSEL = e.prevInAEL;
            e.prevInSEL.nextInSEL = e;
            e.nextInSEL = null;
            e.tmpX = TopX( e, topY );
            e = e.nextInAEL;
              }

              //bubblesort ...
              bool isModified = true;
              while( isModified && m_SortedEdges != null )
              {
            isModified = false;
            e = m_SortedEdges;
            while( e.nextInSEL != null )
            {
              TEdge eNext = e.nextInSEL;
              IntPoint pt = new IntPoint();
              if(e.tmpX > eNext.tmpX && IntersectPoint(e, eNext, ref pt))
              {
                  if (pt.Y > botY)
                  {
                      pt.Y = botY;
                      pt.X = TopX(e, pt.Y);
                  }
                  AddIntersectNode(e, eNext, pt);
                  SwapPositionsInSEL(e, eNext);
                  isModified = true;
              }
              else
                e = eNext;
            }
            if( e.prevInSEL != null ) e.prevInSEL.nextInSEL = null;
            else break;
              }
              m_SortedEdges = null;
        }
 //------------------------------------------------------------------------------
 private void AddLocalMinPoly(TEdge e1, TEdge e2, IntPoint pt)
 {
     if (e2.dx == horizontal || (e1.dx > e2.dx))
     {
         AddOutPt(e1, e2, pt);
         e2.outIdx = e1.outIdx;
         e1.side = EdgeSide.esLeft;
         e2.side = EdgeSide.esRight;
     }
     else
     {
         AddOutPt(e2, e1, pt);
         e1.outIdx = e2.outIdx;
         e1.side = EdgeSide.esRight;
         e2.side = EdgeSide.esLeft;
     }
 }
 //------------------------------------------------------------------------------
 private void AddIntersectNode(TEdge e1, TEdge e2, IntPoint pt)
 {
     IntersectNode newNode = new IntersectNode();
       newNode.edge1 = e1;
       newNode.edge2 = e2;
       newNode.pt = pt;
       newNode.next = null;
       if (m_IntersectNodes == null) m_IntersectNodes = newNode;
       else if( Process1Before2(newNode, m_IntersectNodes) )
       {
     newNode.next = m_IntersectNodes;
     m_IntersectNodes = newNode;
       }
       else
       {
     IntersectNode iNode = m_IntersectNodes;
     while( iNode.next != null  && Process1Before2(iNode.next, newNode) )
         iNode = iNode.next;
     newNode.next = iNode.next;
     iNode.next = newNode;
       }
 }
 //------------------------------------------------------------------------------
 internal bool Pt3IsBetweenPt1AndPt2(IntPoint pt1, IntPoint pt2, IntPoint pt3)
 {
     if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true;
     else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X);
     else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y);
 }
 //------------------------------------------------------------------------------
 // OffsetPolygon functions ...
 //------------------------------------------------------------------------------
 internal static Polygon BuildArc(IntPoint pt, double a1, double a2, double r)
 {
     int steps = Math.Max(6, (int)(Math.Sqrt(Math.Abs(r)) * Math.Abs(a2 - a1)));
     Polygon result = new Polygon(steps);
     int n = steps - 1;
     double da = (a2 - a1) / n;
     double a = a1;
     for (int i = 0; i < steps; ++i)
     {
         result.Add(new IntPoint(pt.X + Round(Math.Cos(a) * r), pt.Y + Round(Math.Sin(a) * r)));
         a += da;
     }
     return result;
 }
Beispiel #29
0
        public static PolyTree ExecuteClipper(TmxMap map, TmxChunk chunk, TransformPointFunc xfFunc)
        {
            ////for(int i=0;i<chunk.Height;i++)
            //// {
            ////     for(int j=0; j<chunk.Width;j++)
            ////     {
            ////         var raw = chunk.GetRawTileIdAt(j, i);
            ////      if(raw!=0)
            ////         {
            ////             var tid = TmxMath.GetTileIdWithoutFlags(raw);
            ////             var tile = map.Tiles[tid];
            ////             foreach(var p in tile.ObjectGroup.Objects)
            ////             {
            ////                 if(p is TmxHasPoints)
            ////                 {
            ////                     p.ToEnumerable().Where((x) =>
            ////                     {
            ////                         if (!usingUnityLayerOverride)
            ////                         {


            ////                             return string.Compare(tuple.Item1.Type, chunk.ParentData.ParentLayer.Name, true) == 0;
            ////                         }

            ////                         return true;
            ////                     });
            ////                 }

            ////             }
            ////         }
            ////     }
            //// }

            //     Clipper clipper = new Clipper(0);
            //     Tuple<TmxObject, TmxTile, uint> tuple = new Tuple<TmxObject, TmxTile, uint>(null, null, 0);
            //     bool usingUnityLayerOverride = !string.IsNullOrEmpty(chunk.ParentData.ParentLayer.UnityLayerOverrideName);
            //     foreach (var item2 in from h__TransparentIdentifier4 in (from y in Enumerable.Range(0, chunk.Height)
            //                                                              from x in Enumerable.Range(0, chunk.Width)
            //                                                              let rawTileId = chunk.GetRawTileIdAt(x, y)
            //                                                              where rawTileId != 0
            //                                                              let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId)
            //                                                              let tile = map.Tiles[tileId]

            //                                                              from polygon in tile.ObjectGroup.Objects
            //                                                              where polygon is TmxHasPoints

            //                                                              select polygon.ToEnumerable().ToList().TrueForAll
            //                                                              (h__TransparentIdentifier4 =>

            //                    {
            //                        UnityEngine.Debug.Log("liudaodelh");
            //                        tuple = new Tuple<TmxObject, TmxTile, uint>(polygon, tile, rawTileId);
            //                        if (!usingUnityLayerOverride)
            //                        {


            //                            return string.Compare(tuple.Item1.Type, chunk.ParentData.ParentLayer.Name, true) == 0;
            //                        }

            //                        return true;
            //                    }))
            //                           select new
            //                           {

            //                               PositionOnMap = map.GetMapPositionAt((int)tuple.Item1.Position.X + chunk.X, (int)tuple.Item1.Position.Y + chunk.Y, tuple.Item2),
            //                               HasPointsInterface = (tuple.Item1 as TmxHasPoints),
            //                               TmxObjectInterface = tuple.Item1,
            //                               IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(tuple.Item3),
            //                               IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(tuple.Item3),
            //                               IsFlippedVertically = TmxMath.IsTileFlippedVertically(tuple.Item3),
            //                               TileCenter = new PointF((float)tuple.Item2.TileSize.Width * 0.5f, (float)tuple.Item2.TileSize.Height * 0.5f)
            //                           })
            //     {
            //         List<IntPoint> list = new List<IntPoint>();
            //         SizeF offset = new SizeF(item2.TmxObjectInterface.Position);
            //         PointF[] array = item2.HasPointsInterface.Points.Select((PointF pt) => PointF.Add(pt, offset)).ToArray();
            //         TmxMath.TransformPoints(array, item2.TileCenter, item2.IsFlippedDiagnoally, item2.IsFlippedHorizontally, item2.IsFlippedVertically);
            //         PointF[] array2 = array;
            //         for (int i = 0; i < array2.Length; i++)
            //         {
            //             PointF pointF = array2[i];
            //             float x2 = (float)item2.PositionOnMap.X + pointF.X;
            //             float y2 = (float)item2.PositionOnMap.Y + pointF.Y;
            //             IntPoint item = xfFunc(x2, y2);
            //             list.Add(item);
            //         }
            //         list.Reverse();
            //         clipper.AddPath(list, PolyType.ptSubject, item2.HasPointsInterface.ArePointsClosed());
            //     }
            //     PolyTree polyTree = new PolyTree();
            //     clipper.Execute(ClipType.ctUnion, polyTree, SubjectFillRule, ClipFillRule);

            //     return polyTree;


            ClipperLib.Clipper clipper = new ClipperLib.Clipper();

            // Limit to polygon "type" that matches the collision layer name (unless we are overriding the whole layer to a specific Unity Layer Name)
            bool usingUnityLayerOverride = !String.IsNullOrEmpty(chunk.ParentData.ParentLayer.UnityLayerOverrideName);

            var polygons = from y in Enumerable.Range(0, chunk.Height)
                           from x in Enumerable.Range(0, chunk.Width)
                           let rawTileId = chunk.GetRawTileIdAt(x, y)
                                           where rawTileId != 0
                                           let tileId                       = TmxMath.GetTileIdWithoutFlags(rawTileId)
                                                                   let tile = map.Tiles[tileId]
                                                                              from polygon in tile.ObjectGroup.Objects
                                                                              where (polygon as TmxHasPoints) != null
                                                                              where usingUnityLayerOverride || String.Compare(polygon.Type, chunk.ParentData.ParentLayer.Name, true) == 0
                                                                              select new
            {
                PositionOnMap         = map.GetMapPositionAt(x + chunk.X, y + chunk.Y, tile),
                HasPointsInterface    = polygon as TmxHasPoints,
                TmxObjectInterface    = polygon,
                IsFlippedDiagnoally   = TmxMath.IsTileFlippedDiagonally(rawTileId),
                IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId),
                IsFlippedVertically   = TmxMath.IsTileFlippedVertically(rawTileId),
                TileCenter            = new PointF(tile.TileSize.Width * 0.5f, tile.TileSize.Height * 0.5f),
            };

            // Add all our polygons to the Clipper library so it can reduce all the polygons to a (hopefully small) number of paths
            foreach (var poly in polygons)
            {
                // Create a clipper library polygon out of each and add it to our collection
                ClipperPolygon clipperPolygon = new ClipperPolygon();

                // Our points may be transformed due to tile flipping/rotation
                // Before we transform them we put all the points into local space relative to the tile
                SizeF    offset            = new SizeF(poly.TmxObjectInterface.Position);
                PointF[] transformedPoints = poly.HasPointsInterface.Points.Select(pt => PointF.Add(pt, offset)).ToArray();

                // Now transform the points relative to the tile
                TmxMath.TransformPoints(transformedPoints, poly.TileCenter, poly.IsFlippedDiagnoally, poly.IsFlippedHorizontally, poly.IsFlippedVertically);

                foreach (var pt in transformedPoints)
                {
                    float x = poly.PositionOnMap.X + pt.X;
                    float y = poly.PositionOnMap.Y + pt.Y;

                    ClipperLib.IntPoint point = xfFunc(x, y);
                    clipperPolygon.Add(point);
                }

                // Because of Unity's cooridnate system, the winding order of the polygons must be reversed
                clipperPolygon.Reverse();

                // Add the "subject"
                clipper.AddPath(clipperPolygon, ClipperLib.PolyType.ptSubject, poly.HasPointsInterface.ArePointsClosed());
            }

            ClipperLib.PolyTree solution = new ClipperLib.PolyTree();
            clipper.Execute(ClipperLib.ClipType.ctUnion, solution, LayerClipper.SubjectFillRule, LayerClipper.ClipFillRule);
            return(solution);
        }
Beispiel #30
0
 public static Poly2Tri.PolygonPoint PP(ClipperLib.IntPoint v)
 {
     return(new Poly2Tri.PolygonPoint(v.X / 16384.0, v.Y / 16384.0));
 }
Beispiel #31
0
 public static Vector2 V2(ClipperLib.IntPoint v)
 {
     return(new Vector2((float)(v.X / 16384.0), (float)(v.Y / 16384.0)));
 }
Beispiel #32
0
    public static Vector2i[] Execute(List <Vector2i> inPolygon, List <List <Vector2f> > outEdges)
    {
        int inVertexCount = inPolygon.Count;

        if (inVertexCount < 2)
        {
            return(null);
        }

        int[] polygonMask = new int[inVertexCount];

        int removeCount = 0;

        if (epsilon > 0f)
        {
            RamerDouglasPeucker(inPolygon, polygonMask, 0, inVertexCount - 1, ref removeCount);
        }

        Vector2i[] outPolygon = new Vector2i[inVertexCount - removeCount];

        List <Vector2f> outEdge = new List <Vector2f>();

        int[] edgeMask = new int[outPolygon.Length];

        int j = 0;

        for (int i = 0; i < inVertexCount; i++)
        {
            if (polygonMask[i] != 1)
            {
                outPolygon[j] = inPolygon[i];
                edgeMask[j]   = GetMask(inPolygon[i]);
                j++;
            }
        }

        int maskPrev, mask, a;

        for (int i = 0; i < edgeMask.Length; i++)
        {
            maskPrev = edgeMask[(i - 1 + edgeMask.Length) % edgeMask.Length];
            mask     = edgeMask[i];
            a        = mask & maskPrev;

            if (mask != 0 && a != 0)
            {
                if (outEdge.Count > 1)
                {
                    outEdges.Add(outEdge);
                    outEdge = new List <Vector2f>();
                }
                else
                {
                    outEdge.Clear();
                }

                outEdge.Add(outPolygon[i].ToVector2f());
            }
            else
            {
                outEdge.Add(outPolygon[i].ToVector2f());
            }
        }

        maskPrev = edgeMask[edgeMask.Length - 1];
        mask     = edgeMask[0];
        a        = mask & maskPrev;

        if (mask != 0 && a != 0)
        {
            if (outEdge.Count > 1)
            {
                outEdges.Add(outEdge);
                outEdge = new List <Vector2f>();
            }
            else
            {
                outEdge.Clear();
            }

            outEdge.Add(outPolygon[0].ToVector2f());
        }
        else
        {
            outEdge.Add(outPolygon[0].ToVector2f());
        }

        if (outEdge.Count > 1)
        {
            outEdges.Add(outEdge);
        }

        return(outPolygon);
    }
Beispiel #33
0
 public static Vector2 GetPoint(ClipperLib.IntPoint pt)
 {
     return(new Vector2((float)pt.X / clipperScale, (float)pt.Y / clipperScale));
 }
 public float GetDistance(Vector2i p)
 {
     return(Mathf.Abs(a * p.x + b * p.y + c));
 }
 public IntPoint(IntPoint pt)
 {
     this.X = pt.X; this.Y = pt.Y;
 }
Beispiel #36
0
        public static PolyTree ExecuteClipper(TmxMap tmxMap, TmxLayer tmxLayer, TransformPointFunc xfFunc, ProgressFunc progFunc)
        {
            // The "fullClipper" combines the clipper results from the smaller pieces
            ClipperLib.Clipper fullClipper = new ClipperLib.Clipper();

            // From the perspective of Clipper lines are polygons too
            // Closed paths == polygons
            // Open paths == lines
            var polygonGroups = from y in Enumerable.Range(0, tmxLayer.Height)
                                from x in Enumerable.Range(0, tmxLayer.Width)
                                let rawTileId = tmxLayer.GetRawTileIdAt(x, y)
                                                let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId)
                                                             where tileId != 0
                                                             let tile = tmxMap.Tiles[tileId]
                                                                        from polygon in tile.ObjectGroup.Objects
                                                                        where (polygon as TmxHasPoints) != null
                                                                        let groupX = x / LayerClipper.GroupBySize
                                                                                     let groupY = y / LayerClipper.GroupBySize
                                                                                                  group new
            {
                PositionOnMap         = tmxMap.GetMapPositionAt(x, y, tile),
                HasPointsInterface    = polygon as TmxHasPoints,
                TmxObjectInterface    = polygon,
                IsFlippedDiagnoally   = TmxMath.IsTileFlippedDiagonally(rawTileId),
                IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId),
                IsFlippedVertically   = TmxMath.IsTileFlippedVertically(rawTileId),
                TileCenter            = new PointF(tile.TileSize.Width * 0.5f, tile.TileSize.Height * 0.5f),
            }
            by Tuple.Create(groupX, groupY);

            int groupIndex = 0;
            int groupCount = polygonGroups.Count();

            foreach (var polyGroup in polygonGroups)
            {
                if (groupIndex % 5 == 0)
                {
                    progFunc(String.Format("Clipping '{0}' polygons: {1}%", tmxLayer.UniqueName, (groupIndex / (float)groupCount) * 100));
                }
                groupIndex++;

                // The "groupClipper" clips the polygons in a smaller part of the world
                ClipperLib.Clipper groupClipper = new ClipperLib.Clipper();

                // Add all our polygons to the Clipper library so it can reduce all the polygons to a (hopefully small) number of paths
                foreach (var poly in polyGroup)
                {
                    // Create a clipper library polygon out of each and add it to our collection
                    ClipperPolygon clipperPolygon = new ClipperPolygon();

                    // Our points may be transformed due to tile flipping/rotation
                    // Before we transform then we put all the points into local space relative to the tile
                    SizeF    offset            = new SizeF(poly.TmxObjectInterface.Position);
                    PointF[] transformedPoints = poly.HasPointsInterface.Points.Select(pt => PointF.Add(pt, offset)).ToArray();

                    // Now transform the points relative to the tile
                    TmxMath.TransformPoints(transformedPoints, poly.TileCenter, poly.IsFlippedDiagnoally, poly.IsFlippedHorizontally, poly.IsFlippedVertically);

                    foreach (var pt in transformedPoints)
                    {
                        float x = poly.PositionOnMap.X + pt.X;
                        float y = poly.PositionOnMap.Y + pt.Y;

                        ClipperLib.IntPoint point = xfFunc(x, y);
                        clipperPolygon.Add(point);
                    }

                    // Because of Unity's cooridnate system, the winding order of the polygons must be reversed
                    clipperPolygon.Reverse();

                    // Add the "subject"
                    groupClipper.AddPath(clipperPolygon, ClipperLib.PolyType.ptSubject, poly.HasPointsInterface.ArePointsClosed());
                }

                // Get a solution for this group
                ClipperLib.PolyTree solution = new ClipperLib.PolyTree();
                groupClipper.Execute(ClipperLib.ClipType.ctUnion, solution);

                // Combine the solutions into the full clipper
                fullClipper.AddPaths(Clipper.ClosedPathsFromPolyTree(solution), PolyType.ptSubject, true);
                fullClipper.AddPaths(Clipper.OpenPathsFromPolyTree(solution), PolyType.ptSubject, false);
            }
            progFunc(String.Format("Clipping '{0}' polygons: 100%", tmxLayer.UniqueName));

            ClipperLib.PolyTree fullSolution = new ClipperLib.PolyTree();
            fullClipper.Execute(ClipperLib.ClipType.ctUnion, fullSolution);

            return(fullSolution);
        }
        //------------------------------------------------------------------------------
        internal static DoublePoint GetUnitNormal(IntPoint pt1, IntPoint pt2)
        {
            double dx = (pt2.X - pt1.X);
            double dy = (pt2.Y - pt1.Y);
            if ((dx == 0) && (dy == 0)) return new DoublePoint();

            double f = 1 * 1.0 / Math.Sqrt(dx * dx + dy * dy);
            dx *= f;
            dy *= f;

            return new DoublePoint(dy, -dx);
        }
 public static Vector3 ToVector3(this Vector2i p)
 {
     return(new Vector3(p.X / CliperLibRatio, p.Y / CliperLibRatio, 0f));
 }
 //------------------------------------------------------------------------------
 internal void SwapPoints(ref IntPoint pt1, ref IntPoint pt2)
 {
     IntPoint tmp = pt1;
     pt1 = pt2;
     pt2 = tmp;
 }
 public static Vector2 ToVector2(this Vector2i p)
 {
     return(new Vector2(p.X / CliperLibRatio, p.Y / CliperLibRatio));
 }
 //------------------------------------------------------------------------------
 private void AddLocalMaxPoly(TEdge e1, TEdge e2, IntPoint pt)
 {
     AddOutPt(e1, null, pt);
     if (e1.outIdx == e2.outIdx)
     {
         e1.outIdx = -1;
         e2.outIdx = -1;
     }
     else AppendPolygon(e1, e2);
 }
 //------------------------------------------------------------------------------
 internal bool PointInPolygon(IntPoint pt, OutPt pp, bool UseFulllongRange)
 {
     OutPt pp2 = pp;
       bool result = false;
       if (UseFulllongRange)
       {
       do
       {
           if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) ||
               ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) &&
               new Int128(pt.X - pp2.pt.X) <
               Int128.Int128Mul(pp2.prev.pt.X - pp2.pt.X,  pt.Y - pp2.pt.Y) /
               new Int128(pp2.prev.pt.Y - pp2.pt.Y))
                 result = !result;
           pp2 = pp2.next;
       }
       while (pp2 != pp);
       }
       else
       {
       do
       {
           if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) ||
             ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) &&
             (pt.X - pp2.pt.X < (pp2.prev.pt.X - pp2.pt.X) * (pt.Y - pp2.pt.Y) /
             (pp2.prev.pt.Y - pp2.pt.Y))) result = !result;
           pp2 = pp2.next;
       }
       while (pp2 != pp);
       }
       return result;
 }
 //------------------------------------------------------------------------------
 private void AddOutPt(TEdge e, TEdge altE, IntPoint pt)
 {
     bool ToFront = (e.side == EdgeSide.esLeft);
       if(  e.outIdx < 0 )
       {
       OutRec outRec = CreateOutRec();
       m_PolyOuts.Add(outRec);
       outRec.idx = m_PolyOuts.Count -1;
       e.outIdx = outRec.idx;
       OutPt op = new OutPt();
       outRec.pts = op;
       outRec.bottomPt = op;
       outRec.bottomE1 = e;
       outRec.bottomE2 = altE;
       op.pt = pt;
       op.idx = outRec.idx;
       op.next = op;
       op.prev = op;
       SetHoleState(e, outRec);
       } else
       {
       OutRec outRec = m_PolyOuts[e.outIdx];
       OutPt op = outRec.pts;
       if (ToFront && PointsEqual(pt, op.pt) ||
           (!ToFront && PointsEqual(pt, op.prev.pt))) return;
       OutPt op2 = new OutPt();
       op2.pt = pt;
       op2.idx = outRec.idx;
       if (op2.pt.Y == outRec.bottomPt.pt.Y &&
         op2.pt.X < outRec.bottomPt.pt.X)
       {
           outRec.bottomPt = op2;
           outRec.bottomE1 = e;
           outRec.bottomE2 = altE;
       }
       op2.next = op;
       op2.prev = op.prev;
       op2.prev.next = op2;
       op.prev = op2;
       if (ToFront) outRec.pts = op2;
       }
 }
 //------------------------------------------------------------------------------
 internal bool PointIsVertex(IntPoint pt, OutPt pp)
 {
     OutPt pp2 = pp;
       do
       {
     if (PointsEqual(pp2.pt, pt)) return true;
     pp2 = pp2.next;
       }
       while (pp2 != pp);
       return false;
 }
Beispiel #45
0
 //---------------------------------------------------------------------
 private IntPoint GenerateRandomPoint(int l, int t, int r, int b, Random rand)
 {
     int Q = 10;
     IntPoint newPt = new IntPoint();
     newPt.X = (rand.Next(r / Q) * Q + l + 10) * scale;
     newPt.Y = (rand.Next(b / Q) * Q + t + 10) * scale;
     return newPt;
 }
 //------------------------------------------------------------------------------
 protected static bool PointsEqual(IntPoint pt1, IntPoint pt2)
 {
     return ( pt1.X == pt2.X && pt1.Y == pt2.Y );
 }
		static public PolyTree FindDistictObjectBounds(ImageBuffer image)
		{
			MarchingSquaresByte marchingSquaresData = new MarchingSquaresByte(image, 5, 0);
			marchingSquaresData.CreateLineSegments();
			Polygons lineLoops = marchingSquaresData.CreateLineLoops(1);

			if (lineLoops.Count == 1)
			{
				return null;
			}

			// create a bounding polygon to clip against
			IntPoint min = new IntPoint(long.MaxValue, long.MaxValue);
			IntPoint max = new IntPoint(long.MinValue, long.MinValue);
			foreach (Polygon polygon in lineLoops)
			{
				foreach (IntPoint point in polygon)
				{
					min.X = Math.Min(point.X - 10, min.X);
					min.Y = Math.Min(point.Y - 10, min.Y);
					max.X = Math.Max(point.X + 10, max.X);
					max.Y = Math.Max(point.Y + 10, max.Y);
				}
			}

			Polygon boundingPoly = new Polygon();
			boundingPoly.Add(min);
			boundingPoly.Add(new IntPoint(min.X, max.Y));
			boundingPoly.Add(max);
			boundingPoly.Add(new IntPoint(max.X, min.Y));

			// now clip the polygons to get the inside and outside polys
			Clipper clipper = new Clipper();
			clipper.AddPaths(lineLoops, PolyType.ptSubject, true);
			clipper.AddPath(boundingPoly, PolyType.ptClip, true);

			PolyTree polyTreeForPlate = new PolyTree();
			clipper.Execute(ClipType.ctIntersection, polyTreeForPlate);

			return polyTreeForPlate;
		}
 //------------------------------------------------------------------------------
 protected bool SlopesEqual(IntPoint pt1, IntPoint pt2,
     IntPoint pt3, IntPoint pt4, bool UseFulllongRange)
 {
     if (pt1.Y == pt2.Y) return (pt3.Y == pt4.Y);
     else if (pt1.X == pt2.X) return (pt3.X == pt4.X);
     else if (UseFulllongRange)
         return Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) ==
           Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y);
     else return
       (Int64)(pt1.Y - pt2.Y) * (pt3.X - pt4.X) - (Int64)(pt1.X - pt2.X) * (pt3.Y - pt4.Y) == 0;
 }
 /// <summary>
 /// Checks if the point is outside of polygon
 /// </summary>
 /// <param name="val">Polygon to check</param>
 /// <param name="point">Point to check</param>
 /// <returns>true if point is outside of polygon</returns>
 public static bool IsOutside(this Geometry.Polygon val, Vector2 point)
 {
     var p = new IntPoint(point.X, point.Y);
     return Clipper.PointInPolygon(p, val.ToClipperPath()) != 1;
 }
 //------------------------------------------------------------------------------
 private void InitEdge(TEdge e, TEdge eNext,
   TEdge ePrev, IntPoint pt, PolyType polyType)
 {
     e.next = eNext;
       e.prev = ePrev;
       e.xcurr = pt.X;
       e.ycurr = pt.Y;
       if (e.ycurr >= e.next.ycurr)
       {
     e.xbot = e.xcurr;
     e.ybot = e.ycurr;
     e.xtop = e.next.xcurr;
     e.ytop = e.next.ycurr;
     e.windDelta = 1;
       } else
       {
     e.xtop = e.xcurr;
     e.ytop = e.ycurr;
     e.xbot = e.next.xcurr;
     e.ybot = e.next.ycurr;
     e.windDelta = -1;
       }
       SetDx(e);
       e.polyType = polyType;
       e.outIdx = -1;
 }