МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ федеральное государственное автономное образовательное учреждение высшего образования «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»
КАФЕДРА №53 «ИФОРМАЦИОННО-СЕТЕВЫХ ТЕХНОЛОГИЙ»
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
ассистент |
|
|
|
В. А. Ушаков |
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ № 2 |
СПЛАЙНОВАЯ КРИВАЯ БЕЗЬЕ |
по курсу: КОМПЬЮТЕРНАЯ ГРАФИКА |
|
|
РАБОТУ ВЫПОЛНИЛA
СТУДЕНТКА ГР. № |
|
|
|
|
|
|
|
|
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург 2021
Цель работы: изучение сплайновой кривой Безье, построение сплайновой кривой Безье с помощью математического пакета и/или языка программирования высокого уровня.
Задание
1. Построить график функции по заданию.
2. На периоде гармонических колебаний взять N точек, где N равно 4 плюс номер студента в группе.
3. По опорным точкам из пункта 2 построить кривую Безье (на том же графике, что и в пункте 1).
4. Рассчитать ошибку восстановления функции по заданию кривой Безье.
5. Уменьшить число точек на периоде в 2 раза и повторить пункты 1-4.
6. Увеличить число точек на периоде в 2 раза и повторить пункты 1-4.
7. Построить кривую Безье на основе полинома N-го порядка (где N берется из пункта 2) и рассчитать ошибку.
Вариант 5
Количество точек N = 9
Функция:
Интервал: σ = 0,5; x = [0,2; 2,5]
Теоретические положения
Функция полинома:
Уравнение сплайновой кривой Безье:
p = polyfit(x, y, n) – возвращает коэффициенты многочлена, корни которого являются элементами x, y – функция для подгона.
y = polyval(p, x) – возвращает значения полинома с коэффициентами p в каждой точке x.
Листинг с кодом программы
figure('name','Безье для функции по заданию (9 точек)');
disp("Ошибка восстановления для функции по заданию (9 точек):");
createFunction(9);
figure('name','Кривая Безье для полинома (9 точек)');
disp("Ошибка функции (9 точек):");
createPolynomial(9);
figure('name','Крвая Безье для функции по заданию (5 точек)');
disp("Ошибка восстановления функции по заданию (5 точек):");
createFunction(round(9/2));
figure('name','Кривая Безье для полинома (5 точек)');
disp("Ошибка восстановления полинома (5 точек):");
createPolynomial(round(9/2));
figure('name','Кривая Безье для функции по заданию (18 точки)');
disp("Ошибка восстановления функции по заданию (18 точки):");
createFunction(9*2);
figure('name','Кривая Безье для полинома (18 точки)');
disp("Ошибка восстановления полинома (18 точки):");
createPolynomial(9*2);
%Функция для построения графика функции по заданию
%и кривой Безье для этого графика, n - количество точек
function createFunction(n)
T = (2.5 - 0.2) / (n-1); %T - периодичность точек на интервале
x = 0.2:T:2.5;
y = (exp(-log(x).^2/(2*0.25)))./(x*0.5*sqrt(2*pi));
hold on
%Построение графика функции
plot(x,y,'b-')
plot(x,y,'ro')
%Ошибка восстановления функции кривой Безье
mistakeFunction = 0;
%Безье для первого участка графика
addX = (x(3) + x(4))/2;
addY = (y(3) + y(4))/2;
for i = 1:1:101
t = (i-1)/100;
xf(i) = (((1-t)*x(1)+3*t*x(2))*(1-t)+3*t*t*x(3))*(1-t)+t*t*t*addX;
ynorm = (exp(-log(xf(i)).^2/(2*0.25)))./(xf(i)*0.5*sqrt(2*pi));
yf(i) = (((1-t)*y(1)+3*t*y(2))*(1-t)+3*t*t*y(3))*(1-t)+t*t*t*addY;
mistakeFunction = mistakeFunction + abs(ynorm - yf(i));
end
%Построение участка кривой Безье
plot(xf,yf,'g-')
%Безье для последнего участка графика
if (mod(n,2) == 0)
addX = (x(n-3) + x(n-2)) / 2;
addY = (y(n-3) + y(n-2)) / 2;
for i = 1:1:101
t = (i-1)/100;
xf(i) = (((1-t)*addX+3*t*x(n-2))*(1-t)+3*t*t*x(n-1))*(1-t)+t*t*t*x(n);
ynorm = (exp(-log(xf(i)).^2/(2*0.25)))./(xf(i)*0.5*sqrt(2*pi));
yf(i) = (((1-t)*addY+3*t*y(n-2))*(1-t)+3*t*t*y(n-1))*(1-t)+t*t*t*y(n);
mistakeFunction = mistakeFunction + abs(ynorm - yf(i));
end
%Построение участка кривой Безье
plot(xf,yf,'g-')
else
addX = (x(n-2) + x(n-1)) / 2;
addY = (y(n-2) + y(n-1)) / 2;
for i = 1:1:101
t = (i-1)/100;
xf(i) = (((1-t)*addX+3*t*x(n-1))*(1-t)+3*t*t*x(n))*(1-t)+t*t*t*x(n);
ynorm = (exp(-log(xf(i)).^2/(2*0.25)))./(xf(i)*0.5*sqrt(2*pi));
yf(i) = (((1-t)*addY+3*t*y(n-1))*(1-t)+3*t*t*y(n))*(1-t)+t*t*t*y(n);
mistakeFunction = mistakeFunction + abs(ynorm - yf(i));
end
%Построение участка кривой Безье
plot(xf,yf,'g-')
end
%Безье для остальных участков
if (n > 6)
num = ceil((n - 6) / 2);
for j = 1:1:num
for i = 1:1:101
t = (i-1)/100;
index = 1 + (2 * j);
addX1 = (x(index) + x(index + 1)) / 2;
addY1 = (y(index) + y(index + 1)) / 2;
addX2 = (x(index + 2) + x(index + 3)) / 2;
addY2 = (y(index + 2) + y(index + 3)) / 2;
xf(i) = (((1-t)*addX1+3*t*x(index + 1))*(1-t)+3*t*t*x(index + 2))*(1-t)+t*t*t*addX2;
ynorm = (exp(-log(xf(i)).^2/(2*0.25)))./(xf(i)*0.5*sqrt(2*pi));
yf(i) = (((1-t)*addY1+3*t*y(index + 1))*(1-t)+3*t*t*y(index + 2))*(1-t)+t*t*t*addY2;
mistakeFunction = mistakeFunction + abs(ynorm - yf(i));
end
%Построение участка кривой Безье
plot(xf,yf,'g-')
end
end
hold off
%Нахождение средней величины ошибки восстановления графика
%функции по заданию (сумма / количество)
mistakeFunction = mistakeFunction / (101 * (n-1))
end
%Функция для построения графика полинома
%и кривой Безье для этого графика, n - количество точек
function createPolynomial(n)
T = (2.5 - 0.2) / (n-1); %T - периодичность точек на интервале
x = 0.2:T:2.5;
y = (exp(-log(x).^2/(2.*0.25)))./(x.*0.5.*sqrt(2.*pi));
f = myFunc(x, y, n);
k = 1:1:n;
hold on
%Построение графика полинома
plot(k,f, 'b-')
plot(k,f, 'ro')
%Ошибка восстановления полинома кривой Безье
mistakePoly = 0;
%Безье для первых 3 точек графика
addX = (k(3) + k(4))/2;
addY = (f(3) + f(4))/2;
for i = 1:1:101
t = (i-1)/100;
xp(i) = (((1-t)*k(1)+3*t*k(2))*(1-t)+3*t*t*k(3))*(1-t)+t*t*t*addX;
ynorm = (exp(-log(xp(i)).^2/(2*0.25)))./(xp(i)*0.5*sqrt(2*pi));
yp(i) = (((1-t)*f(1)+3*t*f(2))*(1-t)+3*t*t*f(3))*(1-t)+t*t*t*addY;
mistakePoly = mistakePoly + abs(ynorm - yp(i));
end
%Построение участка кривой Безье
plot(xp,yp,'g-')
%Безье для последних 3 точек графика
if (mod(n,2) == 0)
addX = (k(n-3) + k(n-2)) / 2;
addY = (f(n-3) + f(n-2)) / 2;
for i = 1:1:101
t = (i-1)/100;
xp(i) = (((1-t)*addX+3*t*k(n-2))*(1-t)+3*t*t*k(n-1))*(1-t)+t*t*t*k(n);
ynorm = (exp(-log(xp(i)).^2/(2*0.25)))./(xp(i)*0.5*sqrt(2*pi));
yp(i) = (((1-t)*addY+3*t*f(n-2))*(1-t)+3*t*t*f(n-1))*(1-t)+t*t*t*f(n);
mistakePoly = mistakePoly + abs(ynorm - yp(i));
end
%Построение участка кривой Безье
plot(xp,yp,'g-')
else
addX = (k(n-2) + k(n-1)) / 2;
addY = (f(n-2) + f(n-1)) / 2;
for i = 1:1:101
t = (i-1)/100;
xp(i) = (((1-t)*addX+3*t*k(n-1))*(1-t)+3*t*t*k(n))*(1-t)+t*t*t*k(n);
ynorm = (exp(-log(xp(i)).^2/(2*0.25)))./(xp(i)*0.5*sqrt(2*pi));
yp(i) = (((1-t)*addY+3*t*f(n-1))*(1-t)+3*t*t*f(n))*(1-t)+t*t*t*f(n);
mistakePoly = mistakePoly + abs(ynorm - yp(i));
end
%Построение участка кривой Безье
plot(xp,yp,'g-')
end
%Безье для остальных участков
if (n > 6)
num = ceil((n - 6) / 2);
for j = 1:1:num
for i = 1:1:101
t = (i-1)/100;
index = 1 + (2 * j);
addX1 = (k(index) + k(index + 1)) / 2;
addY1 = (f(index) + f(index + 1)) / 2;
addX2 = (k(index + 2) + k(index + 3)) / 2;
addY2 = (f(index + 2) + f(index + 3)) / 2;
xp(i) = (((1-t)*addX1+3*t*k(index + 1))*(1-t)+3*t*t*k(index + 2))*(1-t)+t*t*t*addX2;
ynorm = (exp(-log(xp(i)).^2/(2*0.25)))./(xp(i)*0.5*sqrt(2*pi));
yp(i) = (((1-t)*addY1+3*t*f(index + 1))*(1-t)+3*t*t*f(index + 2))*(1-t)+t*t*t*addY2;
mistakePoly = mistakePoly + abs(ynorm - yp(i));
end
%Построение участка кривой Безье
plot(xp,yp,'g-')
end
end
hold off
%Нахождение средней величины ошибки восстановления графика
%полинома (сумма / количество)
mistakePoly = mistakePoly / (101 * (n-1))
end
%Функция для вычисления значения полинома
function f = myFunc(x, y, n)
p = polyfit(x, y, n-1); %Нахождение коэффициентов полинома
for i = 1:1:n
f(i) = polyval(p, i); %Вычисление значения полинома
end
end