#include "CurvePoly.h"
//三次贝塞尔曲线
float bezier3funcX(float uu, cv::Point *controlP){float part0 = controlP[0].x * uu * uu *uu;float part1 = 3 * controlP[1].x * uu * uu * (1 -uu);float part2 = 3 * controlP[2].x * uu * (1 - uu) * (1 -uu);float part3 = controlP[3].x * (1 - uu) * (1 - uu) * (1 -uu);return part0 + part1 + part2 +part3;
}float bezier3funcY(float uu, cv::Point *controlP){float part0 = controlP[0].y * uu * uu *uu;float part1 = 3 * controlP[1].y * uu * uu * (1 -uu);float part2 = 3 * controlP[2].y * uu * (1 - uu) * (1 -uu);float part3 = controlP[3].y * (1 - uu) * (1 - uu) * (1 -uu);return part0 + part1 + part2 +part3;
}void CurvePoly(const std::vector<:point>& vPtsInput, std::vector<:point> &curvePoint)
{//控制点收缩系数 ,经调试0.6较好,cv::Point是opencv的,可自行定义结构体(x,y)
int originCount =vPtsInput.size();float scale = 0.6;
cv::Point* midpoints = newcv::Point[originCount];//生成中点
for (int i = 0; i < originCount; i++){int nexti = (i + 1) %originCount;
midpoints[i].x= (vPtsInput[i].x + vPtsInput[nexti].x) / 2.0;
midpoints[i].y= (vPtsInput[i].y + vPtsInput[nexti].y) / 2.0;
}//平移中点
cv::Point* extrapoints = new cv::Point[2 *originCount];for (int i = 0; i < originCount; i++){int nexti = (i + 1) %originCount;int backi = (i + originCount - 1) %originCount;
cv::Point midinmid;
midinmid.x= (midpoints[i].x + midpoints[backi].x) / 2.0;
midinmid.y= (midpoints[i].y + midpoints[backi].y) / 2.0;int offsetx = vPtsInput[i].x -midinmid.x;int offsety = vPtsInput[i].y -midinmid.y;int extraindex = 2 *i;
extrapoints[extraindex].x= midpoints[backi].x +offsetx;
extrapoints[extraindex].y= midpoints[backi].y +offsety;//朝 originPoint[i]方向收缩
int addx = (extrapoints[extraindex].x - vPtsInput[i].x) *scale;int addy = (extrapoints[extraindex].y - vPtsInput[i].y) *scale;
extrapoints[extraindex].x= vPtsInput[i].x +addx;
extrapoints[extraindex].y= vPtsInput[i].y +addy;int extranexti = (extraindex + 1) % (2 *originCount);
extrapoints[extranexti].x= midpoints[i].x +offsetx;
extrapoints[extranexti].y= midpoints[i].y +offsety;//朝 originPoint[i]方向收缩
addx = (extrapoints[extranexti].x - vPtsInput[i].x) *scale;
addy= (extrapoints[extranexti].y - vPtsInput[i].y) *scale;
extrapoints[extranexti].x= vPtsInput[i].x +addx;
extrapoints[extranexti].y= vPtsInput[i].y +addy;
}
CStdStrFile ssf;
std::vector<:point>vResPts;
cv::Point controlPoint[4];//生成4控制点,产生贝塞尔曲线
for (int i = 0; i < originCount; i++)
{
controlPoint[0] =vPtsInput[i];int extraindex = 2 *i;
controlPoint[1] = extrapoints[extraindex + 1];int extranexti = (extraindex + 2) % (2 *originCount);
controlPoint[2] =extrapoints[extranexti];int nexti = (i + 1) %originCount;
controlPoint[3] =vPtsInput[nexti];float u = 1;while (u >= 0){int px =bezier3funcX(u, controlPoint);int py =bezier3funcY(u, controlPoint);//u的步长决定曲线的疏密
u -= 0.05;
cv::Point tempP=cv::Point(px, py);//存入曲线点
if (!ssf.VectorContains(vResPts, tempP))
{
vResPts.push_back(tempP);
}
}
}//这样做是为了让函数输入和输出可以使用同一个参数
curvePoint =vResPts;delete[] midpoints;
midpoints=nullptr;delete[] extrapoints;
extrapoints=nullptr;
}