多边形切割为多个三角形的C代码,Java代码

原文连接
测试验证可用
qt 界面显示代码:qt5.12 可以直接运行

qt源码
在这里插入图片描述
在这里插入图片描述

Java代码
 static final float EPSILON=0.0000000001f;

    static public float Area(List<PointF> contour)
    {

        int n = contour.size();

        float A=0.0f;

        for(int p=n-1,q=0; q<n; p=q++)
        {
            A+= contour.get(p).x*contour.get(q).y - contour.get(q).x*contour.get(p).y;
        }
        return A*0.5f;
    }

    /*
      InsideTriangle decides if a point P is Inside of the triangle
      defined by A, B, C.
    */
    static public boolean InsideTriangle(float Ax, float Ay,
                                         float Bx, float By,
                                         float Cx, float Cy,
                                         float Px, float Py)

    {
        float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
        float cCROSSap, bCROSScp, aCROSSbp;

        ax = Cx - Bx;  ay = Cy - By;
        bx = Ax - Cx;  by = Ay - Cy;
        cx = Bx - Ax;  cy = By - Ay;
        apx= Px - Ax;  apy= Py - Ay;
        bpx= Px - Bx;  bpy= Py - By;
        cpx= Px - Cx;  cpy= Py - Cy;

        aCROSSbp = ax*bpy - ay*bpx;
        cCROSSap = cx*apy - cy*apx;
        bCROSScp = bx*cpy - by*cpx;

        return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
    };

    static public boolean Snip(List<PointF> contour,int u,int v,int w,int n,int []V)
    {
        int p;
        float Ax, Ay, Bx, By, Cx, Cy, Px, Py;

        Ax = contour.get(V[u]).x;
        Ay = contour.get(V[u]).y;

        Bx = contour.get(V[v]).x;
        By = contour.get(V[v]).y;

        Cx = contour.get(V[w]).x;
        Cy = contour.get(V[w]).y;

        if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false;

        for (p=0;p<n;p++)
        {
            if( (p == u) || (p == v) || (p == w) ) continue;
            Px = contour.get(V[p]).x;
            Py = contour.get(V[p]).y;
            if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
        }

        return true;
    }
	//result保存生成所有三角的点
    public static boolean Process1(List<PointF> contour, List<PointF> result)
    {
        /* allocate and initialize list of Vertices in polygon */

        int n = contour.size();
        if ( n < 3 ) return false;

        int []V = new int[n];

        /* we want a counter-clockwise polygon in V */

        if ( 0.0f < Area(contour) )
            for (int v=0; v<n; v++) V[v] = v;
        else
            for(int v=0; v<n; v++) V[v] = (n-1)-v;

        int nv = n;

        /*  remove nv-2 Vertices, creating 1 triangle every time */
        int count = 2*nv;   /* error detection */

        for(int m=0, v=nv-1; nv>2; )
        {
            /* if we loop, it is probably a non-simple polygon */
            if (0 >= (count--))
            {
                //** Triangulate: ERROR - probable bad polygon!
                return false;
            }

            /* three consecutive vertices in current polygon, <u,v,w> */
            int u = v  ; if (nv <= u) u = 0;     /* previous */
            v = u+1; if (nv <= v) v = 0;     /* new v    */
            int w = v+1; if (nv <= w) w = 0;     /* next     */

            if ( Snip(contour,u,v,w,nv,V) )
            {
                int a,b,c,s,t;

                /* true names of the vertices */
                a = V[u]; b = V[v]; c = V[w];

                /* output Triangle */
                result.add( contour.get(a) );
                result.add( contour.get(b) );
                result.add( contour.get(c) );

                m++;

                /* remove v from remaining polygon */
                for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;

                /* resest error detection counter */
                count = 2*nv;
            }
        }



        return true;
    }
	//result保存所有生成的三角形的点的索引(contour 中的位置) 
    public static boolean Process2(List<PointF> contour, List<Integer> result)
    {
        /* allocate and initialize list of Vertices in polygon */

        int n = contour.size();
        if ( n < 3 ) return false;

        int []V = new int[n];

        /* we want a counter-clockwise polygon in V */

        if ( 0.0f < Area(contour) )
            for (int v=0; v<n; v++) V[v] = v;
        else
            for(int v=0; v<n; v++) V[v] = (n-1)-v;

        int nv = n;

        /*  remove nv-2 Vertices, creating 1 triangle every time */
        int count = 2*nv;   /* error detection */

        for(int m=0, v=nv-1; nv>2; )
        {
            /* if we loop, it is probably a non-simple polygon */
            if (0 >= (count--))
            {
                //** Triangulate: ERROR - probable bad polygon!
                return false;
            }

            /* three consecutive vertices in current polygon, <u,v,w> */
            int u = v  ; if (nv <= u) u = 0;     /* previous */
            v = u+1; if (nv <= v) v = 0;     /* new v    */
            int w = v+1; if (nv <= w) w = 0;     /* next     */

            if ( Snip(contour,u,v,w,nv,V) )
            {
                int a,b,c,s,t;

                /* true names of the vertices */
                a = V[u]; b = V[v]; c = V[w];

                /* output Triangle */
                result.add( a );
                result.add( b );
                result.add( c );

                m++;

                /* remove v from remaining polygon */
                for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;

                /* resest error detection counter */
                count = 2*nv;
            }
        }



        return true;
    }
Java调用
		List<PointF>  a =new ArrayList<>();
		//结果点
        List<PointF>  result =new ArrayList<>();
        //结果点所在的索引
        List<Integer> result1 =new ArrayList<>();
        a.add(new PointF(0,6));
        a.add( new PointF(0,0));
        a.add( new PointF(3,0));
        a.add( new PointF(4,1));
        a.add( new PointF(6,1));
        a.add( new PointF(8,0));
        a.add( new PointF(12,0));
        a.add( new PointF(13,2));
        a.add( new PointF(8,2));
        a.add( new PointF(8,4));
        a.add( new PointF(11,4));
        a.add( new PointF(11,6));
        a.add( new PointF(6,6));
        a.add( new PointF(4,3));
        a.add( new PointF(2,6));

        Triangulate triangulate = new Triangulate();
        triangulate.Process1(a,result);
        triangulate.Process2(a,result1);
        // print out the results.
        int tcount = result.size()/3;

        for (int i=0; i<tcount; i++)
        {
            PointF p1 = result.get(i*3+0);
            PointF p2 = result.get(i*3+1);
            PointF p3 = result.get(i*3+2);

            int i1 = result1.get(i*3+0);
            int i2 = result1.get(i*3+1);
            int i3 = result1.get(i*3+2);


            Log.e("test","Triangle "+i+" =>  "+i1+"---("+p1.x+","+p1.y+")   "+i2+"--- ("+p2.x+","+p2.y+")   "+i3+"--- ("+p3.x+","+p3.y+")");
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dai1396734

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值