-
Notifications
You must be signed in to change notification settings - Fork 1
/
BezierCurve.m
153 lines (136 loc) · 6.04 KB
/
BezierCurve.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
classdef BezierCurve < handle
%BEZIERCURVE Class for handling bezier curves
properties (Constant)
numberOfEvaluationPoints=1000;
end
properties
%initialize control points to empty vector
controlPoints=[];
%default curve is not closed
closedCurve=0;
xValues;
yValues;
xDerivative;
yDerivative;
end
methods
function bezierCurve = calculateBezier(this)
%create a vector of 100 equally spaced points between 0 and 1
linearSpace=linspace(0,1,this.numberOfEvaluationPoints);
%calculate the vector of x positions of the curve
[this.xValues, this.xDerivative]=decastWithDerivative(this.controlPoints(1,:),linearSpace);
disp(this.xValues);
%calculate the vector of y positions of the curve
[this.yValues, this.yDerivative]=decastWithDerivative(this.controlPoints(2,:),linearSpace);
bezierCurve(1,:) = this.xValues;
bezierCurve(2,:) = this.yValues;
end
function [pointX,pointY,xderivative,yderivative] = getDerivativeValue(this,x,y)
%find the neares point and get it derivative
%create array of distance between the searched point and the
%evaluated point
distance = [(this.xValues-x)',(this.yValues-y)'];
%calculate norm of each pair
for i=1:length(distance);
normalized(i) = norm (distance(i));
end
%fid the minimum value (least squares distance)
[~,index] = min(normalized);
%get coordinate value
%return also this for draw precisely the tangent/normal
pointX = this.xValues(index);
pointY = this.yValues(index);
%get derivative value
xderivative = this.xDerivative(index);
yderivative = this.yDerivative(index);
end
function tangent = getTangent(this,x,y)
%get derivative at the given points
[x,y,derivative(1),derivative(2)] = this.getDerivativeValue(x,y);
%linear space between [-1,1] instead of [0,1] for drawing also a backward line
linearSpace = linspace(-1,1,this.numberOfEvaluationPoints);
%normalize vector
derivative(1)=derivative(1)/norm(derivative);
derivative(2)=derivative(2)/norm(derivative);
%create line
tangent(1,:) = x+derivative(1)*(linearSpace);
tangent(2,:) = y+derivative(2)*(linearSpace);
end
function curvature = getCurvature(this,x,y)
%get derivative value at the given points
[x,y,derivative(1),derivative(2)] = this.getDerivativeValue(x,y);
linearSpace = linspace(-1,1,this.numberOfEvaluationPoints);
%determine ortogonal vector
derivative(1)=-derivative(2)/derivative(1);
derivative(2)=1;
%normalize vector
derivative = derivative./norm(derivative);
%create line
normal(1,:) = x+derivative(1)*(linearSpace);
normal(2,:) = y+derivative(2)*(linearSpace);
f=normal(1,500);
disp(this.xValues);
for j=1:length(this.xValues)
disp(j);
if ( f == this.xValues(1,j))
fprintf('L ho trovatoo! è nella posizione %d\n',j)
break
end
end
%________________CURVATURE_____________________
mx = mean(normal(1,500:end));
my = mean(normal(2,500:end));
X = normal(1,500:end) - mx; Y = normal(2,500:end) - my; % Get differences from means
dx2 = mean(X.^2);
dy2 = mean(Y.^2); % Get variances
t = [X,Y]\(X.^2-dx2+Y.^2-dy2)/2; % Solve least mean squares problem
a0 = t(1); b0 = t(2); % t is the 2 x 1 solution array [a0;b0]
r = sqrt(dx2+dy2+a0^2+b0^2); % Calculate the radius
disp(r);
%______________________________________________
fin = 500;
while (fin ~= 1001)
X = [normal(1,500),normal(2,500);normal(1,fin),normal(2,fin)];
d = pdist(X,'euclidean');
if (r - d < 0)
break
end
fin = fin +1;
end
plot(normal(1,500:fin),normal(2,500:fin));
circle(normal(1,fin),normal(2,fin),r);
curvature = r;
end
function normal = getNormal(this,x,y)
%get derivative value at the given points
[x,y,derivative(1),derivative(2)] = this.getDerivativeValue(x,y);
linearSpace = linspace(-1,1,this.numberOfEvaluationPoints);
%determine ortogonal vector
derivative(1)=-derivative(2)/derivative(1);
derivative(2)=1;
%normalize vector
derivative = derivative./norm(derivative);
%create line
normal(1,:) = x+derivative(1)*(linearSpace);
normal(2,:) = y+derivative(2)*(linearSpace);
end
function value=getLength(this)
%function to get the norm of the derivatives
function val = funToIntegrate(this,x)
%mapping index from [0,1] to [1,1000]
index = round((x*(this.numberOfEvaluationPoints-1))+1);
xderiv = this.xDerivative(index);
yderiv = this.yDerivative(index);
val = norm([xderiv,yderiv]);
end
%get left extreme function value
fa = funToIntegrate(this,0);
%get right extreme function value
fb = funToIntegrate(this,1);
%get not composite integral initial value
trapez = trapezoid(0,1,fa,fb);
%get integral value with numeric integration
value = trapezoid_adapt(@(x) funToIntegrate(this,x),0,1,fa,fb,0.001,trapez);
end
end
end