public static zzSimplyPolygon getSubPolygon(zz2DPoint pBeginPoint,zz2DPoint pEndPoint) { if ( pBeginPoint.listNode.List != pEndPoint.listNode.List ) { Debug.LogError("point is not in the polygon"); return null; } zzSimplyPolygon lOut = new zzSimplyPolygon(); //zz2DPoint lNode = pBeginPoint; lOut.bounds = new zz2DBounds(pBeginPoint.position); zz2DPoint lFirstPoint; zz2DPoint lLastPoint; lOut.addOtherPolygonPoint(pBeginPoint, pEndPoint, out lFirstPoint, out lLastPoint); lOut.linkPoint(lLastPoint, lFirstPoint); lOut.checkConcave(lLastPoint); lOut.checkConcave(lFirstPoint); return lOut; }
public zz2DLine(zz2DPoint pFrom, zz2DPoint pTo) { mFrom = pFrom; mTo = pTo; pFrom.setNextLine(this); pTo.setPreviousLine(this); }
/// <summary> /// 合并边与孔 /// </summary> /// <param name="pPolygon1Point"></param> /// <param name="pPolygon2Point"></param> /// <returns></returns> public static zzSimplyPolygon combinePolygon(zz2DPoint pPolygon1Point, zz2DPoint pPolygon2Point) { zzSimplyPolygon lOut = new zzSimplyPolygon(); lOut.bounds = new zz2DBounds(pPolygon1Point.position); zz2DPoint lPolygon1FirstPoint; zz2DPoint lPolygon1LastPoint; lOut.addOtherPolygonPoint(pPolygon1Point, pPolygon1Point, out lPolygon1FirstPoint, out lPolygon1LastPoint); //zz2DPoint l1EndNode = lOut.addOtherPolygonPoint(ref lNode, false); //lOut.linkPoint(lPrePoint, l1EndNode); zz2DPoint lPolygon2FirstPoint; zz2DPoint lPolygon2LastPoint; lOut.addOtherPolygonPoint(pPolygon2Point, pPolygon2Point, out lPolygon2FirstPoint, out lPolygon2LastPoint); lOut.linkPoint(lPolygon1LastPoint, lPolygon2FirstPoint); lOut.linkPoint(lPolygon2LastPoint, lPolygon1FirstPoint); lOut.checkConcave(lPolygon1FirstPoint); lOut.checkConcave(lPolygon1LastPoint); lOut.checkConcave(lPolygon2FirstPoint); lOut.checkConcave(lPolygon2LastPoint); return lOut; }
/// <summary> /// 从同一多边形的两个点连线中,切割图形 /// </summary> /// <param name="pPoint1"></param> /// <param name="pPoint2"></param> /// <returns></returns> public static zzSimplyPolygon[] cut(zz2DPoint pPoint1, zz2DPoint pPoint2) { if (pPoint1.listNode.List == pPoint2.listNode.List) return new zzSimplyPolygon[] { getSubPolygon(pPoint1, pPoint2), getSubPolygon(pPoint2, pPoint1) }; else//切割点一个在孔上 return new zzSimplyPolygon[] { combinePolygon(pPoint1, pPoint2) }; return null; }
public bool isInLine(zz2DPoint pPoint1, zz2DPoint pPoint2) { if (from == pPoint1 || from == pPoint2 || to == pPoint1 || to == pPoint2) return true; return false; }
/// <summary> /// 两点是否可以相连 /// </summary> /// <param name="point1"></param> /// <param name="point2"></param> /// <returns></returns> public bool canLink(zz2DPoint point1,zz2DPoint point2) { //Vector2 v1 = new Vector2(434, 360); //Vector2 v2 = new Vector2(299, 352); //if ((point1.position == v1 && point2.position == v2) // ||(point1.position == v2 && point2.position == v1)) //{ // int i = 0; // ++i; //} bool lCanLink = !point1.isLinked(point2) && point1.isEachInPositiveSide(point2) //&& !mOutSidePoint.isCrossWithLine(point1.position, point2.position); && !mOutSidePoint.isCrossWithLine(point1, point2); if(!lCanLink) return false; foreach (var lHole in mHolePoint) { lCanLink = !lHole.isCrossWithLine(point1, point2); if (!lCanLink) return false; } return lCanLink; }
/// <summary> /// 顺时针围起来的是正 /// </summary> /// <param name="points"></param> public void addShape(Vector2[] points) { if (points.Length < 3) return; zz2DPoint lFirstPoint = new zz2DPoint(points[0]); mPoints.Add(lFirstPoint); zz2DPoint lPrePoint = addPoint(points[1],lFirstPoint); for(int i=2;i<points.Length;++i) { zz2DPoint lNewPoint = addPoint(points[i], lPrePoint); //若新的点在之前的线右边,则之前的角为凸角; //zz2DPoint.LeftOrRight( //lPrePoint.previousPoint.position, //lPrePoint.position, //lNewPoint.position) < 0;//lPrePoint's next point is lNewPoint lPrePoint = lNewPoint; } zz2DPoint lLastPoint = lPrePoint; zz2DLine lLastLine = new zz2DLine(lPrePoint, lFirstPoint); mLines.Add(lLastLine); //lLastPoint.convexAngle = zz2DPoint.LeftOrRight( // lLastPoint.previousPoint.position, // lLastPoint.position, // lLastPoint.nextPoint.position) < 0; //lFirstPoint.convexAngle = zz2DPoint.LeftOrRight( // lFirstPoint.previousPoint.position, // lFirstPoint.position, // lFirstPoint.nextPoint.position) < 0; //sortPoint(mPoints); }
public bool isCrossWithLine(Vector2 lineBegin, Vector2 lineEnd,zz2DPoint exceptPoint) { //先判断有无和边界盒相交 if (!bounds.intersect(lineBegin, lineEnd)) return false; //Debug.Log("bounds.intersect(lineBegin, lineEnd)"); foreach (var lPoint in mAllPoints) { if ( lPoint!=exceptPoint && lPoint.nextPoint!=exceptPoint && lPoint.nextLine.isCrossLine(lineBegin, lineEnd) ) return true; } return false; }
/// <summary> /// 连线是否会被多边形内的其他线截断 /// </summary> /// <param name="lineBegin"></param> /// <param name="lineEnd"></param> /// <returns></returns> public bool isCrossWithLine(zz2DPoint lineBegin, zz2DPoint lineEnd) { //先判断有无和边界盒相交 if (!bounds.intersect(lineBegin.position, lineEnd.position)) return false; //Debug.Log("bounds.intersect(lineBegin, lineEnd)"); foreach (var lPoint in mAllPoints) { if ( //不和lineBegin相连 lPoint != lineBegin && lPoint.nextPoint != lineBegin //不和lineEnd相连 && lPoint != lineEnd && lPoint.nextPoint != lineEnd && lPoint.nextLine.isCrossLine(lineBegin.position, lineEnd.position) ) return true; } return false; }
void checkConcave(zz2DPoint point) { if (point.convexAngle) mConvexPoints.AddLast(point); else mConcavePoints.AddLast(point); }
//public zzSimplyPolygon[] cut(zz2DPoint pPoint1,zz2DPoint pPoint2) //{ // if ( // pPoint1.listNode.List != mAllPoints // || pPoint2.listNode.List != mAllPoints // ) // Debug.LogError("error cut point"); // var lNewPolygonPoints = new List<zz2DPoint>(2); // var lCuted = new zzSimplyPolygon(this, new zz2DPoint[] { pPoint1, pPoint2 }, lNewPolygonPoints); // zz2DPoint lPoint1, lPoint2; // lPoint1 = lNewPolygonPoints[0]; // lPoint2 = lNewPolygonPoints[1]; // return null; //} /// <summary> /// 可用来复制多边形信息 /// </summary> /// <param name="pBeginPoint"></param> /// <param name="pEndPoint"></param> /// <param name="pFirstPoint"></param> /// <param name="pLastPoint"></param> void addOtherPolygonPoint(zz2DPoint pBeginPoint, zz2DPoint pEndPoint, out zz2DPoint pFirstPoint, out zz2DPoint pLastPoint) { zz2DPoint lNode = pBeginPoint; pFirstPoint = addOtherPolygonPoint(ref lNode, false); zz2DPoint lPrePoint = pFirstPoint; //zz2DPoint lEndNode = pEndPoint; while (lNode != pEndPoint) { zz2DPoint lNewPoint = addOtherPolygonPoint(ref lNode); linkPoint(lPrePoint, lNewPoint); lPrePoint = lNewPoint; } pLastPoint = addOtherPolygonPoint(ref lNode, false); linkPoint(lPrePoint, pLastPoint); }
private zz2DPoint addPoint(zzPainterPoint pointPos, zz2DPoint lPrePoint) { zz2DPoint lPoint = new zz2DPoint(pointPos); mPoints.Add(lPoint); zz2DLine lLine = new zz2DLine(lPrePoint, lPoint); mLines.Add(lLine); lPrePoint = lPoint; return lPoint; }
public candidatePointInfo(PointDate pPointDate) { polygonId = pPointDate.polygonId; point = pPointDate.point; scores = 0; }
candidatePointInfo getCandidateConvexPoint(zz2DPoint lPointToSolve) { candidatePointInfo lCandidatePointInfo=new candidatePointInfo(); PointIterator lConvexIterator = new PointIterator(); lConvexIterator.addPolygon(mOutSidePoint.getConvexPoints()); foreach (var lHole in mHolePoint) { lConvexIterator.addPolygon(lHole.getConvexPoints()); } while (lConvexIterator.moveNext() != null) { zz2DPoint lNowPoint = lConvexIterator.nowPointDate.point; if (canLink(lPointToSolve, lNowPoint)) { var lNewCandidatePointInfo = new candidatePointInfo(lConvexIterator.nowPointDate); lNewCandidatePointInfo.scoresUp(); if (isConcaveCleared(lPointToSolve, lNowPoint)) { lNewCandidatePointInfo.scoresUp(candidatePointInfo.scoresOfClearSelfConcave); } if (lNewCandidatePointInfo.scores > lCandidatePointInfo.scores) lCandidatePointInfo = lNewCandidatePointInfo; if (lCandidatePointInfo.scores > candidatePointInfo.scoresOfClearSelfConcave) break; } } return lCandidatePointInfo; }
/// <summary> /// 将point链到newLinked后,point上生成的两个角是否有凹角 /// </summary> /// <param name="point"></param> /// <param name="newLinked"></param> /// <returns></returns> public bool isConcaveCleared(zz2DPoint point,zz2DPoint newLinked) { return zz2DPoint.isConvexPoint(point.previousPoint.position, point.position, newLinked.position) && zz2DPoint.isConvexPoint(newLinked.position, point.position, point.nextPoint.position); }
//public float LeftOrRight(zz2DPoint point) //{ // return zz2DPoint.LeftOrRight(from.position, to.position, point.position); //} public bool isInPositiveSide(zz2DPoint point) { return zz2DPoint.isConvexPoint(from.position, to.position, point.position); }
/// <summary> /// 输入多边形信息 /// </summary> /// <param name="points"></param> public void setShape(Vector2[] points ) { //Debug.Log(points.Length); if (points.Length < 2) { Debug.LogError("points.Length < 2"); return; } shapePoint = points; mConvexPoints = new LinkedList<zz2DPoint>(); mConcavePoints = new LinkedList<zz2DPoint>(); mAllPoints = new LinkedList<zz2DPoint>(); //第一个点 zz2DPoint lFirstPoint = new zz2DPoint(points[0]); bounds = new zz2DBounds(points[0]); lFirstPoint.listNode = mAllPoints.AddLast(lFirstPoint); //第二个点 zz2DPoint lPrePoint = addPoint(points[1], lFirstPoint); for (int i = 2; i < points.Length; ++i) { zz2DPoint lNewPoint = addPoint(points[i], lPrePoint); checkConcave(lPrePoint); lPrePoint = lNewPoint; } zz2DPoint lLastPoint = lPrePoint; linkPoint(lLastPoint, lFirstPoint); checkConcave(lLastPoint); checkConcave(lFirstPoint); //Debug.Log(mAllPoints.Count); }
public bool isDiagonalPoint(zz2DPoint point) { for(int i=0;i<mDiagonals.Count;++i) { if(getDiagonalPoint(i)==point) return true; } return false; }
//class cutHelper //{ // public zzSimplyPolygon cutedPolygon; // public zz2DPoint newBeginPoint; // public zz2DPoint newEndPoint; // public void cut(zzSimplyPolygon otherPolygon,zz2DPoint pBeginPoint,zz2DPoint pEndPoint) // { // cutedPolygon = new zzSimplyPolygon(); // cutedPolygon.bounds = new zz2DBounds(otherPolygon.bounds); // LinkedListNode<zz2DPoint> lNode = otherPolygon.mAllPoints.First // //第一个点 // zz2DPoint lFirstPoint = copyOtherPolygonPoint(lNode); // //第二个点 // zz2DPoint lPrePoint = copyOtherPolygonPoint(lNode); // linkPoint(lFirstPoint,lPrePoint); // while(lNode!=null) // { // zz2DPoint lNewPoint = copyOtherPolygonPoint(lNode); // linkPoint(lPrePoint,lNewPoint); // lPrePoint = lNewPoint; // } // linkPoint(lPrePoint,lFirstPoint); // } // zz2DPoint copyOtherPolygonPoint //} //public zzSimplyPolygon(zzSimplyPolygon otherPolygon, zz2DPoint[] mapPoints, List<zz2DPoint> mapResult ) //{ // bounds = new zz2DBounds(otherPolygon.bounds); // LinkedListNode<zz2DPoint> lNode = otherPolygon.mAllPoints.First; // var lMapPoints = new List<zz2DPoint>(mapPoints); // //第一个点 // zz2DPoint lFirstPoint = copyOtherPolygonPoint(ref lNode, lMapPoints, mapResult); // //第二个点 // zz2DPoint lPrePoint = copyOtherPolygonPoint(ref lNode, lMapPoints, mapResult); // linkPoint(lFirstPoint,lPrePoint); // while(lNode!=null) // { // zz2DPoint lNewPoint = copyOtherPolygonPoint(ref lNode, lMapPoints, mapResult); // linkPoint(lPrePoint,lNewPoint); // lPrePoint = lNewPoint; // } // linkPoint(lPrePoint,lFirstPoint); //} //public zzSimplyPolygon() //{ //} //public zz2DPoint copyOtherPolygonPoint(ref LinkedListNode<zz2DPoint> pNode, List<zz2DPoint> mapPoints, List<zz2DPoint> mapResult) //{ // zz2DPoint lPoint = new zz2DPoint(pNode.Value); // lPoint.listNode = mAllPoints.AddLast(lPoint); // pNode = pNode.Next; // if (lPoint.convexAngle) // mConcavePoints.AddLast(lPoint); // for (int i=0;i<mapPoints.Count; ++i ) // { // if (mapPoints[i] == pNode.Value) // { // mapResult.Add(mapPoints[i]); // mapPoints.RemoveAt(i); // break; // } // } // return lPoint; //} /// <summary> /// 从其他多边形 复制点 /// </summary> /// <param name="pNode"></param> /// <param name="copyConcave">复制凹凸的判断,并将自动检测关闭</param> /// <returns></returns> zz2DPoint addOtherPolygonPoint(ref zz2DPoint pNode, bool copyConcave) { zz2DPoint lPoint = new zz2DPoint(pNode); lPoint.listNode = mAllPoints.AddLast(lPoint); if (copyConcave) { lPoint.convexAngle = pNode.convexAngle; lPoint.autoCheckConvex = false; checkConcave(lPoint); } bounds.encapsulate(lPoint.position); pNode = pNode.nextPoint; return lPoint; }
/// <summary> /// 两点是否都在对方的正面 /// </summary> /// <param name="pOtherPoint"></param> /// <returns></returns> public bool isEachInPositiveSide(zz2DPoint pOtherPoint) { return this.isInPositiveSide(pOtherPoint) && pOtherPoint.isInPositiveSide(this); }
zz2DPoint addOtherPolygonPoint(ref zz2DPoint pNode) { return addOtherPolygonPoint(ref pNode, true); }
/// <summary> /// 参数点是否位于此点两边的正面 /// </summary> /// <param name="pOtherPoint"></param> /// <returns></returns> public bool isInPositiveSide(zz2DPoint pOtherPoint) { if(convexAngle) { return previousLine.isInPositiveSide(pOtherPoint) && nextLine.isInPositiveSide(pOtherPoint) ; } return previousLine.isInPositiveSide(pOtherPoint) || nextLine.isInPositiveSide(pOtherPoint) ; }
/// <summary> /// 创建新点并连接到原来的点,返回创建的新点 /// </summary> /// <param name="pointPos"></param> /// <param name="lPrePoint"></param> /// <returns></returns> private zz2DPoint addPoint(Vector2 pointPos, zz2DPoint lPrePoint) { bounds.encapsulate(pointPos); zz2DPoint lPoint = new zz2DPoint(pointPos); lPoint.listNode = mAllPoints.AddLast(lPoint); //zz2DLine lLine = new zz2DLine(lPrePoint, lPoint); linkPoint(lPrePoint,lPoint); return lPoint; }
public void asExtraLine(zz2DPoint pFrom, zz2DPoint pTo) { mFrom = pFrom; mTo = pTo; }
void linkPoint(zz2DPoint from, zz2DPoint to) { zz2DLine lLine = new zz2DLine(from, to); }
public zz2DPoint(zz2DPoint other) { mPosition = other.mPosition; //convexAngle = other.convexAngle; autoCheckConvex = true; }
public bool isLinked(zz2DPoint pOtherPoint) { return nextPoint == pOtherPoint || previousPoint == pOtherPoint; }
//public bool isCrossLine(zz2DLine otherLine) //{ // return zz2DPoint.isLineSegmentCross(from.position, to.position, // otherLine.from.position, otherLine.to.position); //} /// <summary> /// 是否与两点组成的直线相交 /// </summary> /// <param name="point1"></param> /// <param name="point2"></param> /// <returns></returns> public bool isCrossLine(zz2DPoint point1, zz2DPoint point2) { return isCrossLine(point1.position, point2.position); }