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));
 }
Example #10
0
 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();
    }
Example #17
0
 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();
    }