开发语言:C++
实现平台:Microsoft Visual Studio 6.0
熟悉开发环境,掌握计算机使用DDA
绘制Bezier
曲线的基本原理以及程序编写。
DDA
算法主要是利用了微分的思想,通过同时对x和y各增加一个小增量,计算下一步的x和y值
y i = k x i + b y_i = kx_i + b yi=kxi+b
y i + 1 = k x i + 1 + b = k x i + b + k △ x = y i + k △ x y_{i+1} = kx_{i+1} + b = kx_i + b + k_{\bigtriangleup}x = y_i + k_{\bigtriangleup}x yi+1=kxi+1+b=kxi+b+k△x=yi+k△x
编写源代码如下
#include<stdio.h> #include<graphics.h> #include<math.h> #include<conio.h> void DDA(float x1, float y1, float x2, float y2) { int i, steps; int x0 = 400, y0 = 300; float x, y, delta_x, delta_y, dx, dy; dx = x2 - x1; dy = y2 - y1; if (fabs(dx) >= fabs(dy)) steps = fabs(dx); else steps = fabs(dy); delta_x = float(1.0 * dx / steps); delta_y = float(1.0 * dy / steps); x = x1; y = y1; putpixel((x + x0), (y0 - y), RED); for (i = 1; i <= steps; i++) { x = x + delta_x; y = y + delta_y; putpixel((x + x0), (y0 - int(y + 0.5)), RED); } } void main() { float x1, x2, y1, y2; int x0 = 400, y0 = 300; scanf("%f %f %f %f", &x1, &y1, &x2, &y2); initgraph(800, 600); setbkcolor(WHITE); cleardevice(); setcolor(RED); line(0, y0, x0 * 2, y0); line(x0, 0, x0, y0 * 2); DDA(x1, y1, x2, y2); getchar(); }
绘制出图形如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLLFSb0N-1636039574153)(C:\Users\Lunatic\Desktop\图形学实验报告\图片\IMG_0137.PNG)]
头文件graphics.h
是Turbo C
的图形库,如果要直接使用的话应该用Turbo C
来编译。对于本次实验使用的Microsoft Visual Studio 6.0
平台,采用了下载EasyX
来添加graphics.h
图形库来保证程序的正常编译运行。此方法对于更加现代的集成开发环境如(IDE
)CLion
(并使用MingW64
作为编译器)也一样适用。
开发语言:C++
实现平台:Microsoft Visual Studio 6.0
熟悉开发环境,掌握计算机绘制Bezier
曲线的基本原理以及程序编写。
任意阶的Bezier
曲线表达式
B
n
(
t
)
B_n(t)
Bn(t)可以表示为如下形式
B n ( t ) = ∑ n − 1 k = 0 p k n P k B_n(t) = \sum\limits_{n-1}^{k=0} p_k^n P_k Bn(t)=n−1∑k=0pknPk
本次实验将绘制三次Beizer
曲线,编写源代码如下
#include <graphics.h> #include <math.h> #include <stdio.h> void bezier(int color, double p[4][2]) { double t, t1, t2, xt, yt; int rate = 200, x, y; setcolor(color); moveto(p[0][0], p[0][1]); for (t = 0; t <= 1; t += 1.0 / rate) { yt = 1 - t; t1 = yt * yt; t2 = 3 * yt * t; xt = p[0][0] * t1 * yt + p[1][0] * t2 * yt + p[2][0] * t2 * t + p[3][0] * t * t * t; yt = p[0][1] * yt * t1 + p[1][1] * t2 * yt + p[2][1] * t2 * t + p[3][1] * t * t * t; x = (int) (xt); y = (int) (yt); lineto(x, y); } } void main() { static double p[4][2] = {200, 300, 500, 700, 100, 400, 200, 600}; const NO = 3; int i; int driver = DETECT, mode = 0; initgraph(&driver, &mode); setbkcolor(WHITE); cleardevice(); setcolor(YELLOW); moveto(p[0][0], p[0][1]); for (i = 1; i < NO; i++) lineto(p[i][0], p[i][1]); bezier(LIGHTRED, p); getchar(); }
绘制出图形如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0n21DVx-1636039574157)(C:\Users\Lunatic\Desktop\图形学实验报告\图片\1.jpg)]
Bezier
只需要很少的控制点就能够生成复杂平滑曲线的方法,控制简便却具有极强的描述能力,这使得贝塞尔曲线得到了广泛的应用。
开发语言:Python
实现平台:集成开发环境(IDE
)CLion
,并使用库matplotlib
,numpy
,pandas
,scipy
熟悉开发环境,掌握计算机绘制B样条曲线的基本原理以及程序编写。
B样条曲线的总方程 P ( t ) P(t) P(t)可表示为
P ( t ) = ∑ n − 1 k = 0 P i F i , k ( t ) P(t) = \sum\limits_{n-1}^{k=0}P_iF{i,k}(t) P(t)=n−1∑k=0PiFi,k(t)
将三次B样条曲线基函数带入上式中,可表示为如下形态
P ( t ) = P 0 × F 0 , 3 ( t ) + P 1 × F 1 , 3 ( t ) + P 2 × F 2 , 3 ( t ) + P 3 × F 3 , 3 ( t ) P(t) = P_0 \times F_{0,3}(t) + P_1 \times F_{1,3}(t) + P_2 \times F_{2, 3}(t) + P_3 \times F_{3, 3}(t) P(t)=P0×F0,3(t)+P1×F1,3(t)+P2×F2,3(t)+P3×F3,3(t)
本次实验将模拟三次B
样条插值拟合,编写源代码如下
import matplotlib.pyplot as plt import numpy as np import pandas as pd from scipy import interpolate file = pd.read_csv('data.txt', sep='\s+', names=['index', 'value']) data = pd.DataFrame(file) x = data['index'] y = data['value'] tck = interpolate.splrep(x, y) xx = np.linspace(min(x), max(x), 100) yy = interpolate.splev(xx, tck, der=0) print(yy) plt.plot(xx, yy) plt.show()
数据保存在文件data.txt
中
0 93 30 96 60 84 90 84 120 48 150 38 180 51 210 57 240 40
绘制出图形如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8kJSyNe-1636039574160)(C:\Users\Lunatic\Desktop\图形学实验报告\图片\2.jpg)]
三次B样条曲线拟合轮廓效果较好,较之Beizer
曲线,B样条将一些细节描述的更好。