参考文章:
理解贝塞尔曲线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个顶点
*/
}
效果图