贝塞尔曲线 java

发布于:2024-05-10 ⋅ 阅读:(20) ⋅ 点赞:(0)

参考文章:
理解贝塞尔曲线https://blog.csdn.net/weixin_42301220/article/details/125167672
代码实现参考
https://blog.csdn.net/yinhun2012/article/details/118653732

贝塞尔 一二三阶java代码实现,N阶段可以通过降阶递归实现

public class Test extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        
        //画图测试贝塞尔曲线
        ArrayList<T> list = test1B();
        for (int i = 0; i < list.size(); i++) {
        	//画线的2个点一样即画点
            g2.drawLine((int)list.get(i).p.x,(int)list.get(i).p.y,(int)list.get(i).p.x,(int)list.get(i).p.y);
        }
        list = test2B();
        for (int i = 0; i < list.size(); i++) {
        	//画线的2个点一样即画点
            g2.drawLine((int)list.get(i).p.x,(int)list.get(i).p.y,(int)list.get(i).p.x,(int)list.get(i).p.y);
            if(i%100==0){//展示部分切线
                g2.drawLine((int)list.get(i).a1.x,(int)list.get(i).a1.y,(int)list.get(i).a2.x,(int)list.get(i).a2.y);
            }
        }
        list = test3B();
        for (int i = 0; i < list.size(); i++) {
        	//画线的2个点一样即画点
            g2.drawLine((int)list.get(i).p.x,(int)list.get(i).p.y,(int)list.get(i).p.x,(int)list.get(i).p.y);
            if(i%100==0){//展示部分切线
                g2.drawLine((int)list.get(i).a1.x,(int)list.get(i).a1.y,(int)list.get(i).a2.x,(int)list.get(i).a2.y);
            }
        }
    }

    static class T{
        Point p;
        Point a1;//p的切线起始点
        Point a2;//p的切线结束点
    }

    //测试贝塞尔曲线
    //1阶 2个点
    static T get1Bse(Point p1,Point p2,double t){
        T tp = new T();
        tp.p = new Point();
        tp.a1 = p1;
        tp.a2 = p2;
        tp.p.x = (1-t)*p1.x + t*p2.x;
        tp.p.y = (1-t)*p1.y + t*p2.y;
        return tp;
    }
    static ArrayList<T> test1B(){
        ArrayList<T> list = new ArrayList<>();
        for (int i = 0; i <= 1000; i++) {
            T tt = get1Bse(new Point(100,100,""),new Point(200,200,""),i*0.001);
            list.add(tt);
        }
        return list;
    }
    //2阶 3个点
    static T get2Bse(Point p1,Point p2,Point p3,double t){
        T tp = new T();
        tp.p = new Point();
        tp.a1 = new Point();
        tp.a2 = new Point();
        tp.a1.x = (1-t)*p1.x + t*p2.x;
        tp.a1.y = (1-t)*p1.y + t*p2.y;
        tp.a2.x = (1-t)*p2.x + t*p3.x;
        tp.a2.y = (1-t)*p2.y + t*p3.y;
        tp.p.x = (1-t)*(1-t)*p1.x + 2*t*(1-t)*p2.x + t*t*p3.x;
        tp.p.y = (1-t)*(1-t)*p1.y + 2*t*(1-t)*p2.y + t*t*p3.y;
        return tp;
    }
    static ArrayList<T> test2B(){
        ArrayList<T> list = new ArrayList<>();
        for (int i = 0; i <= 1000; i++) {
            T tt = get2Bse(new Point(100,300,""),new Point(200,300,""),new Point(200,400,""),i*0.001);
            list.add(tt);
        }
        return list;
    }
    //3阶 4个点
    static T get3Bse(Point p1,Point p2,Point p3,Point p4,double t){
        Point p5 = new Point();
        Point p6 = new Point();
        Point p7 = new Point();
        p5.x = (1-t)*p1.x + t*p2.x;
        p5.y = (1-t)*p1.y + t*p2.y;
        p6.x = (1-t)*p2.x + t*p3.x;
        p6.y = (1-t)*p2.y + t*p3.y;
        p7.x = (1-t)*p3.x + t*p4.x;
        p7.y = (1-t)*p3.y + t*p4.y;

        T tp = new T();
        tp.p = new Point();
        tp.a1 = new Point();
        tp.a2 = new Point();
        tp.a1.x = (1-t)*p5.x + t*p6.x;
        tp.a1.y = (1-t)*p5.y + t*p6.y;
        tp.a2.x = (1-t)*p6.x + t*p7.x;
        tp.a2.y = (1-t)*p6.y + t*p7.y;
        tp.p.x = (1-t)*(1-t)*p5.x + 2*t*(1-t)*p6.x + t*t*p7.x;
        tp.p.y = (1-t)*(1-t)*p5.y + 2*t*(1-t)*p6.y + t*t*p7.y;
        return tp;
    }
    static ArrayList<T> test3B(){
        ArrayList<T> list = new ArrayList<>();
        for (int i = 0; i <= 1000; i++) {
            T tt = get3Bse(new Point(100,500,""),new Point(200,600,""),new Point(300,450,""),new Point(400,300,""),i*0.001);
            list.add(tt);
        }
        return list;
    }
    /*
    n阶的实现: todo
因为贝塞尔曲线的规则可以让n个顶点的问题降维到n-1的顶点的计算,那么我们递归套娃,是不是将n个顶点的问题变成由最基本的3个顶点(2阶)计算规则来实现呢?
例如:5个顶点的问题,先降到成4个顶点,再降维到3个顶点
     */
}

效果图
在这里插入图片描述