public static bool isIsolatedPoint(zzPoint pPoint,zzActiveChart tex) { var lDetectDirection = new DetectDirection(); var lNextPoint = lDetectDirection.getOfsetPoint(pPoint); //下一个像素是否可用 var isNextActivePiexl = tex.isInside(lNextPoint) && tex.isActive(lNextPoint); var lNextNextPoint = new zzPoint(); bool isNextNextActivePiexl; for (int i = 0; i < 8;++i ) { lDetectDirection.toNextDirection(); //下下个像素是否可用 lNextNextPoint = lDetectDirection.getOfsetPoint(pPoint); isNextNextActivePiexl = tex.isInside(lNextNextPoint)&&tex.isActive(lNextNextPoint); //连续两个像素可用,则此像素非孤立 if(isNextActivePiexl && isNextNextActivePiexl) return false; isNextActivePiexl = isNextNextActivePiexl; } return true; }
public static Texture2D pick(int[,] pPatternMark,int pPickPatternID, Texture2D pSource, zzPointBounds pBounds, zzPoint pOutSize) { Texture2D lOut = new Texture2D(pOutSize.x, pOutSize.y, TextureFormat.ARGB32, false); var lMin = pBounds.min; var lMax = pBounds.max; var lDrawOffset = -lMin; for (int lY = lMin.y; lY < lMax.y; ++lY) { var lDrawedPointY = lY + lDrawOffset.y; for (int lX = lMin.x; lX < lMax.x; ++lX) { var lColor = pPatternMark[lX, lY] == pPickPatternID ? pSource.GetPixel(lX, lY) : Color.clear; lOut.SetPixel(lX + lDrawOffset.x, lDrawedPointY, lColor); } for (int i = lMax.x+lDrawOffset.x; i < lOut.width; ++i) { lOut.SetPixel(i, lDrawedPointY, Color.clear); } } for (int lY = lMax.y + lDrawOffset.y; lY < lOut.height; ++lY) { for (int lX = 0; lX < lOut.width; ++lX) lOut.SetPixel(lX, lY, Color.clear); } lOut.Apply(); return lOut; }
public void encapsulate(zzPoint point) { mMax.x = Mathf.Max(mMax.x, point.x); mMax.y = Mathf.Max(mMax.y, point.y); mMin.x = Mathf.Min(mMin.x, point.x); mMin.y = Mathf.Min(mMin.y, point.y); }
public zzPointBounds(zzPoint[] points) { mMin = points[0]; mMax = points[0]; for (int i = 1; i < points.Length;++i ) { encapsulate(points[i]); } }
public zzPointBounds(zzPointBounds other) { mMin = other.mMin; mMax = other.mMax; }
public zzPointBounds(zzPoint point) { mMin = point; mMax = point; }
public void setActive(zzPoint pPoint, bool pActive) { setActive(pPoint.x, pPoint.y, pActive); }
public bool isInside(zzPoint pPoint) { return isInside(pPoint.x, pPoint.y); }
static float distance(zzPoint p1, zzPoint p2) { return Mathf.Sqrt(sqrDistance(p1, p2)); }
public static zzPoint operator -(zzPoint p1, zzPoint p2) { zzPoint lPoint = new zzPoint(p1.x - p2.x, p1.y - p2.y); return lPoint; }
public zzPoint getOfsetPoint(zzPoint pPoint) { return new zzPoint(pPoint.x+x,pPoint.y+y); }
// 返回两点之间的距离平方 static float sqrDistance(zzPoint p1, zzPoint p2) { return (float)((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); }
static zzPoint[] simplifyCircleLine(zzPoint[] pLine, float ignoreDistance) { List<zzPoint> lOut = new List<zzPoint>(); lOut.Capacity = pLine.Length/2; List<zzPoint> lStraightLine = new List<zzPoint>(); lStraightLine.Capacity = pLine.Length/2; lOut.Add(pLine[0]); lStraightLine.Add(pLine[0]); lStraightLine.Add(pLine[1]); for (int i = 2; i < pLine.Length;++i ) { //zzPoint lPoint = pLine[i]; //if (lStraightLine.Count == 1) //{ // lStraightLine.Add(lPoint); //} //else //{ zzPoint lPoint = pLine[i]; lStraightLine.Add(lPoint); if (!isStraight(lStraightLine, ignoreDistance)) { //Debug.Log(lStraightLine.Count); zzPoint lEndPoint = lStraightLine[lStraightLine.Count - 2]; lOut.Add(lEndPoint); lStraightLine.Clear(); lStraightLine.Add(lEndPoint); lStraightLine.Add(lPoint); } } lStraightLine.Add(pLine[pLine.Length - 1]); if (!isStraight(lStraightLine, ignoreDistance)) lOut.Add(pLine[pLine.Length - 1]); return lOut.ToArray(); }
static Vector2[] getFloatSimplifyLine(zzPoint[] pLine, float ignoreDistance) { pLine = simplifyCircleLine(pLine, ignoreDistance); Vector2[] lOut = new Vector2[pLine.Length]; for (int i = 0; i < pLine.Length;++i ) { lOut[pLine.Length-i-1] = new Vector2(pLine[i].x, pLine[i].y); } return lOut; }
// a和b是线段的两个端点, c是检测点 //static float sqrDistanceLine(zzPoint a, zzPoint b, zzPoint c) // a和b是线段的两个端点, c是检测点 //{ // zzPoint ab = b - a; // zzPoint ac = c - a; // int f = ab.x * ac.x + ab.y * ac.y; // if (f < 0) // { // //Debug.LogError("f < 0 "); // //Debug.LogError(""+a+"; "+b+"; "+c); // return sqrDistance(a, c); // } // int d = ab.x * ab.x + ab.y + ab.y; // if (f > d) // { // //Debug.LogError(" f > 0 "); // //Debug.LogError("" + a + "; " + b + "; " + c); // return sqrDistance(b, c); // } // f /= d; // zzPoint D; // D.x = a.x + f * ab.x; // c在ab线段上的投影点 // D.y = a.y + f * ab.y; // return sqrDistance(a, D); //} static float distance(zzPoint PA, zzPoint PB, zzPoint P3) { float a, b, c; a = distance(PB, P3); if (a <= 0.00001) return 0.0f; b = distance(PA, P3); if (b <= 0.00001) return 0.0f; c = distance(PA, PB); if (c <= 0.00001) return a;//如果PA和PB坐标相同,则退出函数,并返回距离 //------------------------------ if (a * a >= b * b + c * c)//--------图3-------- return b; //如果是钝角返回b if (b * b >= a * a + c * c)//--------图4------- return a; //如果是钝角返回a //图1 float l = (a + b + c) / 2; //周长的一半 float s = Mathf.Sqrt(l * (l - a) * (l - b) * (l - c)); //海伦公式求面积,也可以用矢量求 return 2 * s / c; }
public override void sweepPicture() { pointNumber = 0; polygonNumber = 0; holeNumber = 0; var lPatternResult = zzOutlineSweeper.sweeper(activeChart); imagePatterns = new Texture2D[lPatternResult.Count]; imagePatternBounds = new zzPointBounds[lPatternResult.Count]; //拾取图块 for (int i = 0; i < lPatternResult.Count; ++i) { zzPointBounds lBounds = lPatternResult.sweeperPointResults[i].Bounds; imagePatternBounds[i] = lBounds; var lBoundMin = lBounds.min; var lBoundMax = lBounds.max; zzPoint lPatternSize = new zzPoint( Mathf.NextPowerOfTwo(lBoundMax.x - lBoundMin.x + 1), Mathf.NextPowerOfTwo(lBoundMax.y - lBoundMin.y + 1) ); imagePatterns[i] = zzImagePatternPicker.pick(lPatternResult.patternMark, i + 1, picture, lBounds, lPatternSize); } //var lSweeperResults = zzOutlineSweeper.sweeper(activeChart, ignoreDistanceInSweeping); var lSweeperResults = zzOutlineSweeper .simplifySweeperResult(lPatternResult.sweeperPointResults, ignoreDistanceInSweeping); modelsSize = new Vector2((float)activeChart.width, (float)activeChart.height); //存储结果 concaves = new List<zz2DConcave>(); var lNewImagePatterns =new List<Texture2D>(lPatternResult.Count); var lNewPatternBounds = new List<zzPointBounds>(lPatternResult.Count); for (int i = 0; i < lSweeperResults.Count; ++i) { var lSweeperResult = lSweeperResults[i]; var lImage = imagePatterns[i]; if (lSweeperResult.edge.Length < 2 || lImage.width < 3 || lImage.height<3) continue; lNewImagePatterns.Add(lImage); lNewPatternBounds.Add(imagePatternBounds[i]); zzSimplyPolygon lPolygon = new zzSimplyPolygon(); lPolygon.setShape(lSweeperResult.edge); zz2DConcave lConcave = new zz2DConcave(); lConcave.setShape(lPolygon); ++polygonNumber; foreach (var lHole in lSweeperResult.holes) { if (lHole.Length < 2) continue; zzSimplyPolygon lHolePolygon = new zzSimplyPolygon(); lHolePolygon.setShape(lHole); lConcave.addHole(lHolePolygon); ++holeNumber; } concaves.Add(lConcave); } imagePatterns = lNewImagePatterns.ToArray(); imagePatternBounds = lNewPatternBounds.ToArray(); }
public bool isActive(zzPoint pPoint) { return isActive(pPoint.x, pPoint.y); }
//static bool isInsideImg(zzPoint pPoint,Texture2D tex) //{ // return pPoint.x >= 0 // && pPoint.x < tex.width // && pPoint.y >= 0 // && pPoint.y < tex.height; //} static zzPoint[] beginEdge(zzActiveChart tex, zzPoint beginPosition, int[,] pProgressdMark, int pMark) { List<zzPoint> lOut = new List<zzPoint>(); lOut.Add(beginPosition); pProgressdMark[beginPosition.x, beginPosition.y] = pMark; DetectDirection lDetectDirection = new DetectDirection(); //int nowX=beginX,nowY=beginY; zzPoint lNowPoint = beginPosition; //int lNextX,lNextY; zzPoint lNextPoint; int lTotalNum = tex.width*tex.height; while(true) { lNextPoint = lDetectDirection.getOfsetPoint(lNowPoint); var lNextDirection = lDetectDirection.nextDirection(); var lNextNextPoint = lNextDirection.getOfsetPoint(lNowPoint); if (tex.isInside(lNextPoint) && tex.isActive(lNextPoint)) { lNowPoint = lNextPoint; if (lNowPoint == beginPosition) break; pProgressdMark[lNowPoint.x, lNowPoint.y] = pMark; lOut.Add(lNowPoint); lDetectDirection.toPreDirection(); lDetectDirection.toPreDirection(); } else { //不可用,继续顺时针寻找 lDetectDirection.toNextDirection(); } if(lOut.Count>lTotalNum) { Debug.LogError("error "); break; } } return lOut.ToArray(); }