Linia Krzywa 2D
Categories:
Zmienne wejściowe:
1. Vertices:
- Macierz M x 2
- Opis: Lista punktów tworzących linię, gdzie każda z M wierszy zawiera współrzędne x i y danego punktu.
- Przykład:
Vertices = [x1, y1; x2, y2; ...; xM, yM]
2. Lines (opcjonalnie):
- Macierz N x 2
- Opis: Lista odcinków linii zdefiniowana przez indeksy punktów z
Vertices. Każdy wiersz zawiera dwa indeksy, które definiują odcinek linii. - Przykład:
Lines = [index1, index2; index2, index3; ...; indexN-1, indexN] - Domyślnie: Jeśli Lines nie jest podane, przyjmuje się, że
Lines = [1 2; 2 3; ...; M-1 M], co oznacza, że punkty są połączone w kolejności, w jakiej są podane.
Zmienna wyjściowa:
1. k:
- Wektor M x 1
- Opis: Wartości krzywizny dla każdego z M punktów linii. Każdy element wektora k odpowiada krzywiźnie w odpowiednim punkcie Vertices.
- Przykład:
k = [k1; k2; ...; kM], gdzie ki to krzywizna w punkcie i.
Przykład użycia:
Jeśli mamy punkty linii:
Vertices = [0, 0; 1, 1; 2, 0; 3, -1];
i chcemy obliczyć krzywiznę, możemy wywołać funkcję:
k = LineCurvature2D(Vertices);
Jeśli chcemy określić własne odcinki linii:
Lines = [1, 2; 2, 3; 3, 4];
k = LineCurvature2D(Vertices, Lines);
Przykłady:
Koło
1. Generowanie losowych kątów:
r = sort(rand(15,1)) * 2 * pi;
- Generujemy 15 losowych liczb w zakresie od 0 do 1
(rand(15,1)). - Sortujemy te liczby rosnąco
(sort). - Przekształcamy je na kąty w zakresie od 0 do 2π poprzez mnożenie przez 2π.
2. Tworzenie punktów okręgu:
Vertices = [sin(r) cos(r)] * 10;
- Używamy funkcji trygonometrycznych sin i cos, aby przekształcić kąty na współrzędne punktów na okręgu.
- Skalujemy współrzędne przez 10, aby uzyskać punkty na okręgu o promieniu 10.
- Vertices to macierz 15x2, gdzie każda para
[sin(r_i) cos(r_i)] * 10reprezentuje współrzędne punktu.
3. Tworzenie linii:
Lines = [(1:size(Vertices,1))' (2:size(Vertices,1)+1']; Lines(end,2) = 1;
- Tworzymy macierz
Lines, która definiuje odcinki linii przez indeksy punktów wVertices. - Każdy wiersz
Linesłączy punkt i z punktem i+1. - Ostatnia para jest specjalnie ustawiona
(Lines(end,2) = 1), aby zamknąć okrąg, łącząc ostatni punkt z pierwszym.
4. Obliczenie krzywizny:
k = LineCurvature2D(Vertices, Lines);
- Wywołujemy funkcję LineCurvature2D z punktami Vertices i liniami Lines, aby obliczyć krzywiznę.
- k to wektor wartości krzywizny dla każdego punktu.
figure, hold on;
- Tworzy nowe okno wykresu.
- Włącza tryb hold on, co pozwala na nałożenie wielu wykresów na jednej figurze bez ich nadpisywania.
5. Obliczenie normalnych do linii:
N = LineNormals2D(Vertices,Lines);
- Wywołuje funkcję LineNormals2D, która oblicza normalne do linii w punktach Vertices na podstawie Lines.
- N to macierz zawierająca wektory normalne dla każdego punktu.
6. Skalowanie wartości krzywizny:
k = k * 100;
- Skaluje wartości krzywizny k przez mnożenie przez 100, aby lepiej widoczne były na wykresie.
- N to macierz zawierająca wektory normalne dla każdego punktu.
7. Wykreślanie normalnych do linii:
plot([Vertices(:,1) Vertices(:,1)+k.*N(:,1)]',[Vertices(:,2) Vertices(:,2)+k.*N(:,2)]','g');
- Wykreśla wektory normalne w każdym punkcie Vertices.
Vertices(:,1)to współrzędne x punktów początkowych.Vertices(:,1) + k.*N(:,1)to współrzędne x końców wektorów normalnych.Vertices(:,2)to współrzędne y punktów początkowych.Vertices(:,2) + k.*N(:,2)to współrzędne y końców wektorów normalnych.- Kolor wykresu: zielony
('g').
8. Wykreślanie linii:
plot([Vertices(Lines(:,1),1) Vertices(Lines(:,2),1)]',[Vertices(Lines(:,1),2) Vertices(Lines(:,2),2)]','b');
-
Wykreśla linie łączące punkty z Vertices zgodnie z Lines.
-
Vertices(Lines(:,1),1)iVertices(Lines(:,2),1)to współrzędne x punktów początkowych i końcowych odcinków linii. -
Vertices(Lines(:,1),2)iVertices(Lines(:,2),2)to współrzędne y punktów początkowych i końcowych odcinków linii. -
Kolor wykresu: niebieski
('b').
9. Wykreślanie idealnego okręgu:
plot(sin(0:0.01:2*pi)*10, cos(0:0.01:2*pi)*10, 'r.');
-
Wykreśla idealny okrąg o promieniu 10.
-
sin(0:0.01:2*pi)*10icos(0:0.01:2*pi)*10to współrzędne x i y punktów na okręgu. -
Kolor wykresu: czerwony
('r').
10. Ustawienie równej skali osi:
axis equal;
- Ustawia równe jednostki na osiach x i y, co sprawia, że okrąg wygląda proporcjonalnie.
Przykład, Ręka:
1. Wczytanie danych z pliku:
load('testdata');
- Wczytuje dane z pliku
testdata.mat, które zawierają zmienneVertices(współrzędne punktów) iLines(lista odcinków linii).
2. Obliczenie krzywizny linii:
k = LineCurvature2D(Vertices, Lines);
- Wywołuje funkcję
LineCurvature2D, która oblicza wartości krzywizny dla punktów zdefiniowanych wVerticesiLines. kto wektor zawierający wartości krzywizny dla każdego punktu.
3. Utworzenie nowej figury i włączenie trybu hold on:
figure, hold on;
- Tworzy nowe okno wykresu.
- Włącza tryb hold on, co pozwala na nałożenie wielu wykresów na jednej figurze bez ich nadpisywania.
4. Obliczenie normalnych do linii:
N = LineNormals2D(Vertices, Lines);
- Wywołuje funkcję
LineNormals2D, która oblicza wektory normalne dla punktów zVerticesna podstawieLines. Nto macierz zawierająca wektory normalne dla każdego punktu.
5. Skalowanie wartości krzywizny:
k = k * 100;
- Skaluje wartości krzywizny
kprzez mnożenie przez 100, aby lepiej widoczne były na wykresie.
6. Wykreślanie normalnych do linii:
plot([Vertices(:,1) Vertices(:,1) + k .* N(:,1)]', [Vertices(:,2) Vertices(:,2) + k .* N(:,2)]', 'g');
- Wykreśla wektory normalne w każdym punkcie
Vertices. Vertices(:,1)to współrzędne x punktów początkowych.Vertices(:,1) + k .* N(:,1)to współrzędne x końców wektorów normalnych.Vertices(:,2)to współrzędne y punktów początkowych.Vertices(:,2) + k .* N(:,2)to współrzędne y końców wektorów normalnych.- Kolor wykresu: zielony
('g').
7. Wykreślanie linii:
plot([Vertices(Lines(:,1),1) Vertices(Lines(:,2),1)]', [Vertices(Lines(:,1),2) Vertices(Lines(:,2),2)]', 'b');
`
- Wykreśla linie łączące punkty z
Verticeszgodnie zLines. Vertices(Lines(:,1),1)iVertices(Lines(:,2),1)to współrzędne x punktów początkowych i końcowych odcinków linii.Vertices(Lines(:,1),2)iVertices(Lines(:,2),2)to współrzędne y punktów początkowych i końcowych odcinków linii.- Kolor wykresu: niebieski
('b').
8. Wykreślanie punktów:
plot(Vertices(:,1), Vertices(:,2), 'r.');
- Wykreśla punkty
Vertices. - Kolor wykresu: czerwony
('r').
9. Ustawienie równej skali osi:
axis equal;
- Ustawia równe jednostki na osiach x i y, co zapewnia proporcjonalne wyświetlanie.
10. Lista zmiennych i ich opis:
Vertices:
- Typ: Macierz M x 2
- Opis: Współrzędne punktów (wierzchołków) linii.
Lines:
- Typ: Macierz N x 2
- Opis: Lista odcinków linii, zdefiniowana przez indeksy punktów w
Vertices.
k:
- Typ: Wektor M x 1
- Opis: Wartości krzywizny dla punktów Vertices, skalowane przez 100.
N:
- Typ: Macierz M x 2
- Opis: Wektory normalne dla punktów z Vertices, obliczone przez LineNormals2D.
Funkcja
Obliczenie krzywizny linii na podstawie zadanych wierzchołków (Vertices) i odcinków linii (Lines). Obejmuje on kroki takie jak uzupełnianie brakujących sąsiadów, przeliczanie wektorów normalnych oraz obliczanie krzywizny na podstawie dopasowania wielomianu do wierzchołków.
Kod:
% Function is written by D.Kroon University of Twente (August 2011)
% If no line-indices, assume a x(1) connected with x(2), x(3) with x(4) ...
if(nargin<2)
Lines=[(1:(size(Vertices,1)-1))' (2:size(Vertices,1))'];
end
% Get left and right neighbor of each points
Na=zeros(size(Vertices,1),1); Nb=zeros(size(Vertices,1),1);
Na(Lines(:,1))=Lines(:,2); Nb(Lines(:,2))=Lines(:,1);
% Check for end of line points, without a left or right neighbor
checkNa=Na==0; checkNb=Nb==0;
Naa=Na; Nbb=Nb;
Naa(checkNa)=find(checkNa); Nbb(checkNb)=find(checkNb);
% If no left neighbor use two right neighbors, and the same for right...
Na(checkNa)=Nbb(Nbb(checkNa)); Nb(checkNb)=Naa(Naa(checkNb));
% Correct for sampeling differences
Ta=-sqrt(sum((Vertices-Vertices(Na,:)).^2,2));
Tb=sqrt(sum((Vertices-Vertices(Nb,:)).^2,2));
% If no left neighbor use two right neighbors, and the same for right...
Ta(checkNa)=-Ta(checkNa); Tb(checkNb)=-Tb(checkNb);
% Fit a polygons to the vertices
% x=a(3)*t^2 + a(2)*t + a(1)
% y=b(3)*t^2 + b(2)*t + b(1)
% we know the x,y of every vertice and set t=0 for the vertices, and
% t=Ta for left vertices, and t=Tb for right vertices,
x = [Vertices(Na,1) Vertices(:,1) Vertices(Nb,1)];
y = [Vertices(Na,2) Vertices(:,2) Vertices(Nb,2)];
M = [ones(size(Tb)) -Ta Ta.^2 ones(size(Tb)) zeros(size(Tb)) zeros(size(Tb)) ones(size(Tb)) -Tb Tb.^2];
invM=inverse3(M);
a(:,1)=invM(:,1,1).*x(:,1)+invM(:,2,1).*x(:,2)+invM(:,3,1).*x(:,3);
a(:,2)=invM(:,1,2).*x(:,1)+invM(:,2,2).*x(:,2)+invM(:,3,2).*x(:,3);
a(:,3)=invM(:,1,3).*x(:,1)+invM(:,2,3).*x(:,2)+invM(:,3,3).*x(:,3);
b(:,1)=invM(:,1,1).*y(:,1)+invM(:,2,1).*y(:,2)+invM(:,3,1).*y(:,3);
b(:,2)=invM(:,1,2).*y(:,1)+invM(:,2,2).*y(:,2)+invM(:,3,2).*y(:,3);
b(:,3)=invM(:,1,3).*y(:,1)+invM(:,2,3).*y(:,2)+invM(:,3,3).*y(:,3);
% Calculate the curvature from the fitted polygon
k = 2*(a(:,2).*b(:,3)-a(:,3).*b(:,2)) ./ ((a(:,2).^2+b(:,2).^2).^(3/2));
function Minv = inverse3(M)
% This function does inv(M) , but then for an array of 3x3 matrices
adjM(:,1,1)= M(:,5).*M(:,9)-M(:,8).*M(:,6);
adjM(:,1,2)= -(M(:,4).*M(:,9)-M(:,7).*M(:,6));
adjM(:,1,3)= M(:,4).*M(:,8)-M(:,7).*M(:,5);
adjM(:,2,1)= -(M(:,2).*M(:,9)-M(:,8).*M(:,3));
adjM(:,2,2)= M(:,1).*M(:,9)-M(:,7).*M(:,3);
adjM(:,2,3)= -(M(:,1).*M(:,8)-M(:,7).*M(:,2));
adjM(:,3,1)= M(:,2).*M(:,6)-M(:,5).*M(:,3);
adjM(:,3,2)= -(M(:,1).*M(:,6)-M(:,4).*M(:,3));
adjM(:,3,3)= M(:,1).*M(:,5)-M(:,4).*M(:,2);
detM=M(:,1).*M(:,5).*M(:,9)-M(:,1).*M(:,8).*M(:,6)-M(:,4).*M(:,2).*M(:,9)+M(:,4).*M(:,8).*M(:,3)+M(:,7).*M(:,2).*M(:,6)-M(:,7).*M(:,5).*M(:,3);
Minv=bsxfun(@rdivide,adjM,detM);
Kroki działania:
1. Sprawdzenie i przypisanie domyślnych indeksów linii:
if(nargin<2) Lines=[(1:(size(Vertices,1)-1))' (2:size(Vertices,1))']; end
- Jeśli nie podano
Lines, domyślnie zakłada, że punkty są połączone sekwencyjnie.
2. Znalezienie lewego i prawego sąsiada dla każdego punktu:
Na=zeros(size(Vertices,1),1); Nb=zeros(size(Vertices,1),1); Na(Lines(:,1))=Lines(:,2); Nb(Lines(:,2))=Lines(:,1);
NaiNbprzechowują indeksy lewych i prawych sąsiadów dla każdego punktu.
3. Sprawdzenie punktów bez sąsiadów i uzupełnienie braków:
checkNa=Na==0; checkNb=Nb==0;
Naa=Na; Nbb=Nb;
Naa(checkNa)=find(checkNa); Nbb(checkNb)=find(checkNb);
Na(checkNa)=Nbb(Nbb(checkNa)); Nb(checkNb)=Naa(Naa(checkNb));
- Jeśli punkt nie ma lewego lub prawego sąsiada, używa dwóch sąsiadów z przeciwnej strony.
4. Korekta różnic próbkowania:
Ta=-sqrt(sum((Vertices-Vertices(Na,:)).^2,2));
Tb=sqrt(sum((Vertices-Vertices(Nb,:)).^2,2));
Ta(checkNa)=-Ta(checkNa); Tb(checkNb)=-Tb(checkNb);
- Oblicza odległości do sąsiadów, uwzględniając brakujące wartości.
5. Dopasowanie wielomianu do wierzchołków:
x = [Vertices(Na,1) Vertices(:,1) Vertices(Nb,1)]; y = [Vertices(Na,2) Vertices(:,2) Vertices(Nb,2)]; M = [ones(size(Tb)) -Ta Ta.^2 ones(size(Tb)) zeros(size(Tb)) zeros(size(Tb)) ones(size(Tb)) -Tb Tb.^2]; invM=inverse3(M); a(:,1)=invM(:,1,1).*x(:,1)+invM(:,2,1).*x(:,2)+invM(:,3,1).*x(:,3); a(:,2)=invM(:,1,2).*x(:,1)+invM(:,2,2).*x(:,2)+invM(:,3,2).*x(:,3); a(:,3)=invM(:,1,3).*x(:,1)+invM(:,2,3).*x(:,2)+invM(:,3,3).*x(:,3); b(:,1)=invM(:,1,1).*y(:,1)+invM(:,2,1).*y(:,2)+invM(:,3,1).*y(:,3); b(:,2)=invM(:,1,2).*y(:,1)+invM(:,2,2).*y(:,2)+invM(:,3,2).*y(:,3); b(:,3)=invM(:,1,3).*y(:,1)+invM(:,2,3).*y(:,2)+invM(:,3,3).*y(:,3);
- Dopasowuje wielomiany do współrzędnych punktów, biorąc pod uwagę sąsiadów.
6. Obliczenie krzywizny:
k = 2*(a(:,2).*b(:,3)-a(:,3).*b(:,2)) ./ ((a(:,2).^2+b(:,2).^2).^(3/2));
7. Odwracanie macierzy 3x3:
function Minv = inverse3(M)
adjM(:,1,1)= M(:,5).*M(:,9)-M(:,8).*M(:,6);
adjM(:,1,2)= -(M(:,4).*M(:,9)-M(:,7).*M(:,6));
adjM(:,1,3)= M(:,4).*M(:,8)-M(:,7).*M(:,5);
adjM(:,2,1)= -(M(:,2).*M(:,9)-M(:,8).*M(:,3));
adjM(:,2,2)= M(:,1).*M(:,9)-M(:,7).*M(:,3);
adjM(:,2,3)= -(M(:,1).*M(:,8)-M(:,7).*M(:,2));
adjM(:,3,1)= M(:,2).*M(:,6)-M(:,5).*M(:,3);
adjM(:,3,2)= -(M(:,1).*M(:,6)-M(:,4).*M(:,3));
adjM(:,3,3)= M(:,1).*M(:,5)-M(:,4).*M(:,2);
detM=M(:,1).*M(:,5).*M(:,9)-M(:,1).*M(:,8).*M(:,6)-M(:,4).*M(:,2).*M(:,9)+M(:,4).*M(:,8).*M(:,3)+M(:,7).*M(:,2).*M(:,6)-M(:,7).*M(:,5).*M(:,3);
Minv=bsxfun(@rdivide,adjM,detM);
Lista zmiennych i ich opis:
Vertices:
- Typ: Macierz M x 2
- Opis: Współrzędne punktów (wierzchołków) linii.
Lines:
- Typ: Macierz N x 2
- Opis: Lista odcinków linii, zdefiniowana przez indeksy punktów w Vertices.
Na:
- Typ: Wektor M x 1
- Opis: Indeksy lewych sąsiadów dla każdego punktu.
Nb:
- Typ: Wektor M x 1
- Opis: Indeksy prawych sąsiadów dla każdego punktu.
checkNa, checkNb:
- Typ: Wektory logiczne M x 1
- Opis: Wskazuje, które punkty nie mają lewego lub prawego sąsiada.
Naa, Nbb:
- Typ: Wektory M x 1
- Opis: Kopie Na i Nb, używane do uzupełniania braków.
Ta, Tb:
- Typ: Wektory M x 1
- Opis: Odległości do lewych i prawych sąsiadów.
x, y:`
- Typ: Macierze M x 3
- Opis: Współrzędne x i y dla punktów i ich sąsiadów.
M:
- Typ: Macierz M x 9
- Opis: Macierz współczynników dla dopasowania wielomianu.
invM:
- Typ: Macierz M x 3 x 3
- Opis: Odwrotność macierzy M.
a, b:
- Typ: Macierze M x 3
- Opis: Współczynniki wielomianów dopasowanych do współrzędnych x i y.
k:
- Typ: Wektor M x 1
- Opis: Wartości krzywizny dla punktów Vertices.