/*
* 三次贝塞尔拟合java实现
*/
public void createCurve(List<Vector3f> originPoint,int originCount,List<Vector3f> curvePoint){
double scale = 0.6;
List<Vector3f> midpoints = new ArrayList<>();
//生成中点
for(int i = 0 ;i +1< originCount ; i++){
int nexti = (i + 1) % originCount;
Vector3f v = new Vector3f(0, 0, 0);
v.setX((originPoint.get(i).getX() + originPoint.get(nexti).getX())/2.0);
v.setY((originPoint.get(i).getY() + originPoint.get(nexti).getY())/2.0);
midpoints.add(v);
}
//平移中点
List<Vector3f> extrapoints = new ArrayList<>();
for(int i = 0 ;i +1< originCount ; i++){
int backi = (i + originCount -2) %( originCount-1);
Vector3f midinmid = new Vector3f(0, 0, 0);
midinmid.setX((midpoints.get(i).getX() + midpoints.get(backi).getX())/2.0);
midinmid.setY((midpoints.get(i).getY() + midpoints.get(backi).getY())/2.0);
double offsetx = originPoint.get(i).getX() - midinmid.getX();
double offsety = originPoint.get(i).getY() - midinmid.getY();
int extraindex = 2 * i;
Vector3f v = new Vector3f(0, 0, 0);
v.setX (midpoints.get(backi).getX() + offsetx);
v.setY(midpoints.get(backi).getY() + offsety);
extrapoints.add(extraindex,v);
//朝 originPoint[i]方向收缩
double addx = (extrapoints.get(extraindex).getX() - originPoint.get(i).getX()) * scale;
double addy = (extrapoints.get(extraindex).getY() - originPoint.get(i).getY()) * scale;
Vector3f v1 = new Vector3f(0, 0, 0);
v1.setX(originPoint.get(i).getX() + addx);
v1.setY(originPoint.get(i).getY() + addy);
extrapoints.set(extraindex,v1);
int extranexti = (extraindex + 1)%(2 * (originCount-1));
Vector3f v2 = new Vector3f(0, 0, 0);
v2.setX(midpoints.get(i).getX() + offsetx);
v2.setY(midpoints.get(i).getY() + offsety);
extrapoints.add(extranexti,v2);
//朝 originPoint[i]方向收缩
addx = (extrapoints.get(extranexti).getX() - originPoint.get(i).getX()) * scale;
addy = (extrapoints.get(extranexti).getY() - originPoint.get(i).getY()) * scale;
Vector3f v3 = new Vector3f(0, 0, 0);
v3.setX(originPoint.get(i).getX() + addx);
v3.setY(originPoint.get(i).getY() + addy);
extrapoints.set(extranexti, v3);
}
Vector3f[] controlPoint = new Vector3f[4];
//生成4控制点,产生贝塞尔曲线
for(int i = 0 ;i+1< originCount ; i++){
controlPoint[0] = originPoint.get(i);
int extraindex = 2 * i;
controlPoint[1] = extrapoints.get(extraindex + 1);
int extranexti = (extraindex + 2) % (2 * (originCount-1));
controlPoint[2] = extrapoints.get(extraindex + 1);
int nexti = (i + 1) % originCount;
controlPoint[3] = originPoint.get(nexti);
double u = 1;
while(u >= 0){
double px = bezier3funcX(u,controlPoint);
double py = bezier3funcY(u,controlPoint);
//u的步长决定曲线的疏密
u -= 0.005;
Vector3f tempP = new Vector3f(px,py,0);
//存入曲线点
curvePoint.add(tempP);
}
}
}
//三次贝塞尔曲线
private double bezier3funcX(double uu, Vector3f[] controlP){
double part0 = controlP[0].getX() * uu * uu * uu;
double part1 = 3 * controlP[1].getX() * uu * uu * (1 - uu);
double part2 = 3 * controlP[2].getX() * uu * (1 - uu) * (1 - uu);
double part3 = controlP[3].getX() * (1 - uu) * (1 - uu) * (1 - uu);
return part0 + part1 + part2 + part3;
}
private double bezier3funcY(double uu, Vector3f[] controlP){
double part0 = controlP[0].getY() * uu * uu * uu;
double part1 = 3 * controlP[1].getY() * uu * uu * (1 - uu);
double part2 = 3 * controlP[2].getY() * uu * (1 - uu) * (1 - uu);
double part3 = controlP[3].getY() * (1 - uu) * (1 - uu) * (1 - uu);
return part0 + part1 + part2 + part3;
}
三次贝塞尔拟合工具
最新推荐文章于 2022-03-01 23:28:00 发布