中国企业在线,江苏seo培训,动漫与游戏制作专业有前途吗,wordpress 内嵌播放器games 101 作业4 题目题解作业答案 题目
Bzier 曲线是一种用于计算机图形学的参数曲线。在本次作业中#xff0c;你需要实 现 de Casteljau 算法来绘制由 4 个控制点表示的 Bzier 曲线 (当你正确实现该 算法时#xff0c;你可以支持绘制由更多点来控制的 Bzier 曲线)。 你需… games 101 作业4 题目题解作业答案 题目
Bézier 曲线是一种用于计算机图形学的参数曲线。在本次作业中你需要实 现 de Casteljau 算法来绘制由 4 个控制点表示的 Bézier 曲线 (当你正确实现该 算法时你可以支持绘制由更多点来控制的 Bézier 曲线)。 你需要修改的函数在提供的 main.cpp 文件中。 • bezier该函数实现绘制 Bézier 曲线的功能。它使用一个控制点序列和一个 OpenCVMat 对象作为输入没有返回值。它会使 t 在 0 到 1 的范围内进 行迭代并在每次迭代中使 t 增加一个微小值。对于每个需要计算的 t将 调用另一个函数 recursive_bezier然后该函数将返回在 Bézier 曲线上 t 处的点。最后将返回的点绘制在 OpenCV Mat 对象上。 • recursive_bezier该函数使用一个控制点序列和一个浮点数 t 作为输入 实现 de Casteljau 算法来返回 Bézier 曲线上对应点的坐标。 De Casteljau 算法说明如下
考虑一个 p0, p1, … pn 为控制点序列的 Bézier 曲线。首先将相邻的点连接 起来以形成线段。用 t : (1 − t) 的比例细分每个线段并找到该分割点。得到的分割点作为新的控制点序列新序列的长度会减少一。如果序列只包含一个点则返回该点并终止。否则使用新的控制点序列并 转到步骤 1。 使用 [0,1] 中的多个不同的 t 来执行上述算法你就能得到相应的 Bézier 曲 线
提升部分 实现对 Bézier 曲线的反走样。(对于一个曲线上的点不只把它对应于一个像 素你需要根据到像素中心的距离来考虑与它相邻的像素的颜色。)
题解
本次作业的难度适中用递归的方式实现n次贝塞尔曲线。
根据算法说明以及贝塞尔函数的定义实现如下算法给定若干个点和t,返回这若干个控制点构成的贝塞尔曲线中t时刻的点。
cv::Point2f recursive_bezier(const std::vectorcv::Point2f control_points, float t)
{if (control_points.size() 1)return control_points[0];std::vectorcv::Point2f new_control_points;for (int i 0; i control_points.size() -1; i){cv::Point2f p t * control_points[i] (1 - t) * control_points[i 1];new_control_points.emplace_back(p);}return recursive_bezier(new_control_points,t);
}然后t 从0到1步进值可自定义本代码中设置为0.001也就是一条贝塞尔由1001个点组成每个点的G通道设置为255也就是线条颜色为绿色。
void bezier(const std::vectorcv::Point2f control_points, cv::Mat window)
{// TODO: Iterate through all t 0 to t 1 with small steps, and call de Casteljaus // recursive Bezier algorithm.int neighborXIndex[8] { 0,1,0,-1,-1,1,-1,1};int neighborYIndex[8] { 1,0,-1,0.1,1,-1,-1};for (double t 0.0; t 1.0; t 0.001){auto point recursive_bezier(control_points,t);window.atcv::Vec3b(point.y, point.x)[1] 255;}
}提升抗锯齿 根据点的位置到所在像素中心点距离以及到相邻像素中心点的距离计算相邻像素的颜色值。可以是四邻或者八邻下面以四邻距离说明 假设当前像素Q点的颜色值为 c o l o r Q color_{Q} colorQ 则ABCD的颜色值分别为 c o l o r A ∣ P Q ∣ / ∣ P A ∣ ∗ c o l o r Q color_{A}|PQ|/|PA| * color_{Q} colorA∣PQ∣/∣PA∣∗colorQ c o l o r B ∣ P Q ∣ / ∣ P B ∣ ∗ c o l o r Q color_{B}|PQ|/|PB| * color_{Q} colorB∣PQ∣/∣PB∣∗colorQ c o l o r C ∣ P Q ∣ / ∣ P C ∣ ∗ c o l o r Q color_{C}|PQ|/|PC| * color_{Q} colorC∣PQ∣/∣PC∣∗colorQ c o l o r D ∣ P Q ∣ / ∣ P D ∣ ∗ c o l o r Q color_{D}|PQ|/|PD| * color_{Q} colorD∣PQ∣/∣PD∣∗colorQ 代码如下
void bezier(const std::vectorcv::Point2f control_points, cv::Mat window)
{// TODO: Iterate through all t 0 to t 1 with small steps, and call de Casteljaus // recursive Bezier algorithm.int neighborXIndex[4] { 0,1,0,-1};int neighborYIndex[4] { 1,0,-1,0};for (double t 0.0; t 1.0; t 0.001){auto point recursive_bezier(control_points,t);window.atcv::Vec3b(point.y, point.x)[1] 255;int x point.x;int y point.y;cv::Point2f p1(x 0.5, y 0.5);float d1 std::sqrt(std::pow(point.x - p1.x, 2) std::pow(point.y - p1.y, 2));for (int i 0; i 4; i){cv::Point2f p(x neighborXIndex[i]*0.5,y neighborYIndex[i]*0.5);float d std::sqrt(std::pow(point.x - p.x, 2) std::pow(point.y - p.y, 2));window.atcv::Vec3b(y neighborYIndex[i], x neighborXIndex[i])[1] d1 / d * 255;}}}总结 贝塞尔函数的定义比较简单n次贝塞尔的函数的定义公式如下 B ( t ) ∑ i 0 n ( n i ) P i ( 1 − t ) n − i 1 t i B(t)\sum_{i0}^n\binom{n}{i} P_i(1-t)^{n-i_1} t^i B(t)∑i0n(in)Pi(1−t)n−i1ti 所以也可以不用递归而是通过这个公式实现N次贝塞尔函数。 一条贝塞尔打断成两端贝塞尔同时保持断点初过渡平滑可以参考博文
作业答案
本次作业的答案放在的git仓库中作业地址