WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Berechnung äquidistanter Punkte entlang eines Polygonzuges

 

Sascha
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.02.16
Wohnort: Stuttgart
Version: R2015b
     Beitrag Verfasst am: 13.02.2016, 19:51     Titel: Berechnung äquidistanter Punkte entlang eines Polygonzuges
  Antworten mit Zitat      
Hallo MATLAB Community,

mein Ziel ist, neue Punkte P_abs(i) in gleichen Abständen d auf dem Polygonzug der Punktematrix P zu berechnen.
Die Abschnitte werden mathematisch in Form von Stützvektor + Richtungsvektor: P + rvP ausgedrückt.
Die Punktematrix wird mehrere hundert Punkte haben, und die Abstände d sollen im voraus eingegeben werden.
Anhand des folgenden Beispiels mit nur 8 Punkten (Start-/Zielpunkt doppelt) und dem Abstand von 0,2 wird gezeigt, wie ich es realisieren möchte.


Code:
% Punktematrix P
P = [3,1;2,0.5;0.75,1;0.5,2;1.5,4;5,3.5;6,2;3,1];

% Berechnung der Punktabstände pa bzw. Längen der Abschnitte
l = length (P);
pa = zeros (l,1);

for i = 1:(l-1)
    pa(i) = sqrt((P(i+1,1) - P(i,1)).^2 + (P(i+1,2) - P(i,2)).^2);
end

pa(l) = [];

% Kummulierter Abstand pa_cum
pa_cum = cumsum(pa);

% Gewünschter Abstand d zwischen den Stützstellen
d = 0.2;

% Abstandsvektor AV
% av = 0:d:max(pa_cum);

% Berechnung der Richtungsvektoren des Polygonzugs
rvP = zeros(l-1,2);

for i = 1:l-1
    rvP(:,1) = diff(P(:,1));
    rvP(:,2) = diff(P(:,2));
end

% Anzahl der Punkte auf Abschnitt 1 (mit floor abrunden)
An_P_abs1 = floor(pa(1)/d);

% Äquidistante Punkte auf Abschnitt 1
P_abs1 = zeros(An_P_abs1,2);

for i = 1:An_P_abs1
    P_abs1(i,:) = P(1,:) + i*(d/pa(1))*rvP(1,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 1
P_end_abs1 = P_abs1(An_P_abs1,:);

% Berechnung des 1.Punktes auf Abschnitt 2:

% Bedingung (1) für 1.Punkt auf Abschnitt 2:
% d = sqrt((P_1abs2(1,1) - P_end_abs1(1,1)).^2 + (P_1abs2(1,2) - P_end_abs1(1,2)).^2

% Bedingung (2) für 1.Punkt auf Abschnitt 2:
% P_1abs2(1,:) = P(2,:) + r*rvP(2,:)

% (2) in (1) und nach Parameter r aufgelöst (mit Mitternachtsformel: r = 1/(2*a) * (+-b + sqrt(b^2 - 4*a*c))):
% Variablen Mitternachtsformel a, b, c

a = rvP(2,1).^2 + rvP(2,2).^2;
b = 2.*P(2,1).*rvP(2,1) - 2.*P_end_abs1(1,1).*rvP(2,1) + 2.*P(2,2).*rvP(2,2) - 2.*P_end_abs1(1,2).*rvP(2,2);
c = P(2,1).^2 - 2.*P_end_abs1(1,1).*P(2,1) + P_end_abs1(1,1).^2 + P(2,2).^2 - 2.*P_end_abs1(1,2).*P(2,2) + P_end_abs1(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs2 = 1/(2*a) * (-b + sqrt(b^2 - 4*a*c));
r2_abs2 = 1/(2*a) * (-b - sqrt(b^2 - 4*a*c));

% (3) in (1) ergibt Koordinatenpunkt P1_abs2
if (0<= r1_abs2) && (r1_abs2 < 1)
    P1_abs2 = P(2,:) + r1_abs2*rvP(2,:);
elseif (0<= r2_abs2) && (r2_abs2 < 1)
    P1_abs2 = P(2,:) + r2_abs2*rvP(2,:);
end

% Ab hier wieder das gleiche wie in Zeile 31 mit dem Unterschied, dass der
% erste Punkt des neuen Abschnitts nicht auf P(2,:) liegt, sondern um
% r1_abs2 * rvP verschoben wurde.
% Somit gilt für die Anzahl der Punkte auf Abschnitt 2:

An_P_abs2 = floor((1-r1_abs2)*pa(2)/d);

% Äquidistante Punkte auf Abschnitt 2
P_abs2 = zeros(An_P_abs2,2);

for i = 1:An_P_abs2
    P_abs2(i,:) = P1_abs2 + i*(d/pa(2))*rvP(2,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 2
P_end_abs2 = P_abs2(An_P_abs2,:);

% 1.Punkt auf Abschnitt 3:

a3 = rvP(3,1).^2 + rvP(3,2).^2;
b3 = 2.*P(3,1).*rvP(3,1) - 2.*P_end_abs2(1,1).*rvP(3,1) + 2.*P(3,2).*rvP(3,2) - 2.*P_end_abs2(1,2).*rvP(3,2);
c3 = P(3,1).^2 - 2.*P_end_abs2(1,1).*P(3,1) + P_end_abs2(1,1).^2 + P(3,2).^2 - 2.*P_end_abs2(1,2).*P(3,2) + P_end_abs2(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs3 = 1/(2*a3) * (-b3 + sqrt(b3^2 - 4*a3*c3));
r2_abs3 = 1/(2*a3) * (-b3 - sqrt(b3^2 - 4*a3*c3));

% (3) in (1) ergibt Koordinatenpunkt P1_abs3
if (0<= r1_abs3) && (r1_abs3 < 1)
    P1_abs3 = P(3,:) + r1_abs3*rvP(3,:);
elseif (0<= r2_abs3) && (r2_abs3 < 1)
    P1_abs3 = P(3,:) + r2_abs3*rvP(3,:);
end

% Ab hier wieder das gleiche wie in Zeile 71
An_P_abs3 = floor((1-r1_abs3)*pa(3)/d);

% Äquidistante Punkte auf Abschnitt 3
P_abs3 = zeros(An_P_abs3,2);

for i = 1:An_P_abs3
    P_abs3(i,:) = P1_abs3 + i*(d/pa(3))*rvP(3,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 3
P_end_abs3 = P_abs3(An_P_abs3,:);

% 1.Punkt auf Abschnitt 4:

a4 = rvP(4,1).^2 + rvP(4,2).^2;
b4 = 2.*P(4,1).*rvP(4,1) - 2.*P_end_abs3(1,1).*rvP(4,1) + 2.*P(4,2).*rvP(4,2) - 2.*P_end_abs3(1,2).*rvP(4,2);
c4 = P(4,1).^2 - 2.*P_end_abs3(1,1).*P(4,1) + P_end_abs3(1,1).^2 + P(4,2).^2 - 2.*P_end_abs3(1,2).*P(4,2) + P_end_abs3(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs4 = 1/(2*a4) * (-b4 + sqrt(b4^2 - 4*a4*c4));
r2_abs4 = 1/(2*a4) * (-b4 - sqrt(b4^2 - 4*a4*c4));

% (3) in (1) ergibt Koordinatenpunkt P1_abs4
if (0<= r1_abs4) && (r1_abs4 < 1)
    P1_abs4 = P(4,:) + r1_abs4*rvP(4,:);
elseif (0<= r2_abs4) && (r2_abs4 < 1)
    P1_abs4 = P(4,:) + r2_abs4*rvP(4,:);
end

% Ab hier wieder das gleiche wie in Zeile 71 und 106
An_P_abs4 = floor((1-r1_abs4)*pa(4)/d);

% Äquidistante Punkte auf Abschnitt 4
P_abs4 = zeros(An_P_abs4,2);

for i = 1:An_P_abs4
    P_abs4(i,:) = P1_abs4 + i*(d/pa(4))*rvP(4,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 4
P_end_abs4 = P_abs4(An_P_abs4,:);

% 1.Punkt auf Abschnitt 5:

a5 = rvP(5,1).^2 + rvP(5,2).^2;
b5 = 2.*P(5,1).*rvP(5,1) - 2.*P_end_abs4(1,1).*rvP(5,1) + 2.*P(5,2).*rvP(5,2) - 2.*P_end_abs4(1,2).*rvP(5,2);
c5 = P(5,1).^2 - 2.*P_end_abs4(1,1).*P(5,1) + P_end_abs4(1,1).^2 + P(5,2).^2 - 2.*P_end_abs4(1,2).*P(5,2) + P_end_abs4(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs5 = 1/(2*a5) * (-b5 + sqrt(b5^2 - 4*a5*c5));
r2_abs5 = 1/(2*a5) * (-b5 - sqrt(b5^2 - 4*a5*c5));

% (3) in (1) ergibt Koordinatenpunkt P1_abs5
if (0<= r1_abs5) && (r1_abs5 < 1)
    P1_abs5 = P(5,:) + r1_abs5*rvP(5,:);
elseif (0<= r2_abs5) && (r2_abs5 < 1)
    P1_abs5 = P(5,:) + r2_abs5*rvP(5,:);
end

% Ab hier wieder das gleiche wie in Zeile 71, 106 und 137
An_P_abs5 = floor((1-r1_abs5)*pa(5)/d);

% Äquidistante Punkte auf Abschnitt 5
P_abs5 = zeros(An_P_abs5,2);

for i = 1:An_P_abs5
    P_abs5(i,:) = P1_abs5 + i*(d/pa(5))*rvP(5,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 5
P_end_abs5 = P_abs5(An_P_abs5,:);

% 1.Punkt auf Abschnitt 6:

a6 = rvP(6,1).^2 + rvP(6,2).^2;
b6 = 2.*P(6,1).*rvP(6,1) - 2.*P_end_abs5(1,1).*rvP(6,1) + 2.*P(6,2).*rvP(6,2) - 2.*P_end_abs5(1,2).*rvP(6,2);
c6 = P(6,1).^2 - 2.*P_end_abs5(1,1).*P(6,1) + P_end_abs5(1,1).^2 + P(6,2).^2 - 2.*P_end_abs5(1,2).*P(6,2) + P_end_abs5(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs6 = 1/(2*a6) * (-b6 + sqrt(b6^2 - 4*a6*c6));
r2_abs6 = 1/(2*a6) * (-b6 - sqrt(b6^2 - 4*a6*c6));

% (3) in (1) ergibt Koordinatenpunkt P1_abs6
if (0<= r1_abs6) && (r1_abs6 < 1)
    P1_abs6 = P(6,:) + r1_abs6*rvP(6,:);
elseif (0<= r2_abs6) && (r2_abs6 < 1)
    P1_abs6 = P(6,:) + r2_abs6*rvP(6,:);
end

% Ab hier wieder das gleiche wie in Zeile 71, 106, 137 und 168
An_P_abs6 = floor((1-r1_abs6)*pa(6)/d);

% Äquidistante Punkte auf Abschnitt 6
P_abs6 = zeros(An_P_abs6,2);

for i = 1:An_P_abs6
    P_abs6(i,:) = P1_abs6 + i*(d/pa(6))*rvP(6,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 6
P_end_abs6 = P_abs6(An_P_abs6,:);

% 1.Punkt auf Abschnitt 7:

a7 = rvP(7,1).^2 + rvP(7,2).^2;
b7 = 2.*P(7,1).*rvP(7,1) - 2.*P_end_abs6(1,1).*rvP(7,1) + 2.*P(7,2).*rvP(7,2) - 2.*P_end_abs6(1,2).*rvP(7,2);
c7 = P(7,1).^2 - 2.*P_end_abs6(1,1).*P(7,1) + P_end_abs6(1,1).^2 + P(7,2).^2 - 2.*P_end_abs6(1,2).*P(7,2) + P_end_abs6(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs7 = 1/(2*a7) * (-b7 + sqrt(b7^2 - 4*a7*c7));
r2_abs7 = 1/(2*a7) * (-b7 - sqrt(b7^2 - 4*a7*c7));

% (3) in (1) ergibt Koordinatenpunkt P1_abs7
if (0<= r1_abs7) && (r1_abs7 < 1)
    P1_abs7 = P(7,:) + r1_abs7*rvP(7,:);
elseif (0<= r2_abs7) && (r2_abs7 < 1)
    P1_abs7 = P(7,:) + r2_abs7*rvP(7,:);
end

% Ab hier wieder das gleiche wie in Zeile 71, 106, 137, 168 und 199
An_P_abs7 = floor((1-r1_abs7)*pa(7)/d);

% Äquidistante Punkte auf Abschnitt 7
P_abs7 = zeros(An_P_abs7,2);

for i = 1:An_P_abs7
    P_abs7(i,:) = P1_abs7 + i*(d/pa(7))*rvP(7,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 7
P_end_abs7 = P_abs7(An_P_abs7,:);

% 1.Punkt auf Abschnitt 8 enspricht Start-/Zielpunkt P(1,:)

% Neue Punktematrix P_neu
P_neu = [P(1,:);P_abs1;P1_abs2;P_abs2;P1_abs3;P_abs3;P1_abs4;P_abs4;P1_abs5;P_abs5;P1_abs6;P_abs6;P1_abs7;P_abs7;P(1,:)];


figure
plot(P(:,1),P(:,2),'or-','Linewidth',2)

hold on
plot(P_neu(:,1),P_neu(:,2),'.b:')



Bis zum Abstand von 0,5 funktioniert es wie gewünscht. Größere Abstände erfordern einen Sprung auf den nächsten Abschnitt und sind noch nicht im Code umgesetzt.
Mein Hauptanliegen ist jedoch, die Berechnung der Abschnittspunkte in eine Schleife zu bekommen, um nicht die Schritte in Zeile 31, 71, 106, 137, 168 und 199 für ein paar hundert Abschnitte abtippen zu müssen.
Kann mir diesbezüglich bitte jemand weiterhelfen?

Eine sehr elegante Lösung ist in

http://www.gomatlab.de/kurvenintegr.....tegral-t27911.html#110308

dargestellt.
Im Gegensatz zu meinem Problem mit vielen Vektoren handelt es sich hierbei nur um EINE Funktion bzw. Polynom.
Ausserdem verstehe ich die Zeile


Code:



nicht. Ein i ausserhalb der Schleife?

Die Zeilen


Code:
x_S = NaN(1, size(AV,2));                      % Stützstellen
for i = 1:size(AV,2)
    [bla index] = min(abs(r_cum - AV(i)));
    x_S(i) = x(index);
end



sind mir ein absolutes Rätsel.
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 13.02.2016, 20:52     Titel: Re: Berechnung äquidistanter Punkte entlang eines Polygonzu
  Antworten mit Zitat      
Hallo Sascha,

Ich arbeite an einer kompakten Form für beliebig viele Punkte. Das könnte vielleicht bis morgen funktionieren.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Sascha
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.02.16
Wohnort: Stuttgart
Version: R2015b
     Beitrag Verfasst am: 15.02.2016, 00:59     Titel:
  Antworten mit Zitat      
Hallo Jan,

das wäre echt klasse!

Im Prinzip besteht das Problem darin, dass ohne den letzten Punkt auf den Abschnitten keine neue Einteilung im neuen Abschnitt möglich ist.
Ich wüßte auch nicht man sie im voraus berechnen könnte, um eine Schleife drumherum zu basteln.

Viele Grüße
Sascha
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 15.02.2016, 12:48     Titel:
  Antworten mit Zitat      
Hallo Sascha,
Zitat:
Im Prinzip besteht das Problem darin, dass ohne den letzten Punkt auf den Abschnitten keine neue Einteilung im neuen Abschnitt möglich ist.

Das verstehe ich nicht.
Du möchtest eigentlich nur Punkt in bestimmtem Abstand auf einem Polygonzug verteilen, oder? Das ist eine lineare Interpolation zwischen den Stützstellen. Mit interp1 solltest Du da also eigentlich eine einfache Lösung hinbekommen. Ich versuche es nur gerade bequemer und effizienter zu lösen.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Sascha
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.02.16
Wohnort: Stuttgart
Version: R2015b
     Beitrag Verfasst am: 15.02.2016, 15:34     Titel:
  Antworten mit Zitat      
Hallo Jan,


bitte entschuldige die unpräzise Formulierung.

Mit der
- Länge der Abschnitte bzw. Punktabstände pa(i),
- Anzahl der Punkte pro Abschnitts An_P_abs = pa(i)/d,
ergeben die Koordinaten bei einer Einteilung von d=0,2 für den letzten Punkt auf Abschnitt 1 ungefähr (2,1/0,55).
Um den Abstand von 0,2 einzuhalten, startet der erste Punkt des 2. Abschnitts P1_abs2 startet also nicht bei P(2,Smile, siehe Abb.1.

Somit liegt der letzte Punkt von Abschnitt 2 nicht auf P_abs2(i,Smile = P(2,Smile + i*(d/pa(2))*rvP(2,Smile, sondern um r1 versetzt.

Die Berechung der Punkte für Abschnitt 1 und des Parameter r1,2 für den darauffolgenden Abschnitt erfolgt im Code zwischen den Zeilen 31 und 69. Dies wiederholt sich bei 8 gegebenen Punkten 7 mal.

Code:
% Anzahl der Punkte auf Abschnitt 1 (mit floor abrunden)
An_P_abs1 = floor(pa(1)/d);

% Äquidistante Punkte auf Abschnitt 1
P_abs1 = zeros(An_P_abs1,2);

for i = 1:An_P_abs1
    P_abs1(i,:) = P(1,:) + i*(d/pa(1))*rvP(1,:);
end

% Sprung auf nächsten Vektor (Abschnittswechsel)
% Letzter Punkt auf Abschnitt 1
P_end_abs1 = P_abs1(An_P_abs1,:);

% Berechnung des 1.Punktes auf Abschnitt 2:

% Bedingung (1) für 1.Punkt auf Abschnitt 2:
% d = sqrt((P_1abs2(1,1) - P_end_abs1(1,1)).^2 + (P_1abs2(1,2) - P_end_abs1(1,2)).^2

% Bedingung (2) für 1.Punkt auf Abschnitt 2:
% P_1abs2(1,Smile = P(2,Smile + r*rvP(2,Smile

% (2) in (1) und nach Parameter r aufgelöst (mit Mitternachtsformel: r = 1/(2*a) * (+-b + sqrt(b^2 - 4*a*c))):
% Variablen Mitternachtsformel a, b, c

a = rvP(2,1).^2 + rvP(2,2).^2;
b = 2.*P(2,1).*rvP(2,1) - 2.*P_end_abs1(1,1).*rvP(2,1) + 2.*P(2,2).*rvP(2,2) - 2.*P_end_abs1(1,2).*rvP(2,2);
c = P(2,1).^2 - 2.*P_end_abs1(1,1).*P(2,1) + P_end_abs1(1,1).^2 + P(2,2).^2 - 2.*P_end_abs1(1,2).*P(2,2) + P_end_abs1(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs2 = 1/(2*a) * (-b + sqrt(b^2 - 4*a*c));
r2_abs2 = 1/(2*a) * (-b - sqrt(b^2 - 4*a*c));

% (3) in (1) ergibt Koordinatenpunkt P1_abs2
if (0<= r1_abs2) && (r1_abs2 < 1)
    P1_abs2 = P(2,:) + r1_abs2*rvP(2,:);
elseif (0<= r2_abs2) && (r2_abs2 < 1)
    P1_abs2 = P(2,:) + r2_abs2*rvP(2,:);
end


Um die Wiederholungen in eine Schleife zu bekommen sind die Koordinaten des jeweils letzten Abschnittspunkts erforderlich (vgl. Zitat).

Vielen Dank mit

Code:


Nach so einer Lösung (oder ähnlich) habe ich gesucht. Daher das Beispiel mit dem Abstandsvektor. Damit würde man gleichmäßige Abstände pro Abschnitt bzw. Funktion erhalten.
Da es sich hierbei um mehrere verschiedene Geradengleichungen handelt, bestehend aus Stütz- und Richtungsvektor, haben die letzten Punkte der Abschnitte nicht diesselben Abstände zu den ersten Punkten des darauffolgenden Abschnitts.
Außerdem unterscheiden sich die Punktabstände auf den einzelnen Abschnitten (siehe Abb.2).

Zitat:
Du möchtest eigentlich nur Punkt in bestimmtem Abstand auf einem Polygonzug verteilen, oder?


Ganz geanu, perfekt herausgelesen!


Viele Grüße
Sascha

Abb.2.JPG
 Beschreibung:
Abb. 2

Download
 Dateiname:  Abb.2.JPG
 Dateigröße:  52.4 KB
 Heruntergeladen:  354 mal
Abb.1.JPG
 Beschreibung:
Abb. 1

Download
 Dateiname:  Abb.1.JPG
 Dateigröße:  57.95 KB
 Heruntergeladen:  335 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 15.02.2016, 16:56     Titel:
  Antworten mit Zitat      
Hallo Sascha,

Zitat:
Mit der
- Länge der Abschnitte bzw. Punktabstände pa(i),
- Anzahl der Punkte pro Abschnitts An_P_abs = pa(i)/d,
ergeben die Koordinaten bei einer Einteilung von d=0,2 für den letzten Punkt auf Abschnitt 1 ungefähr (2,1/0,55).
Um den Abstand von 0,2 einzuhalten, startet der erste Punkt des 2. Abschnitts P1_abs2 startet also nicht bei P(2,:), siehe Abb.1.

Somit liegt der letzte Punkt von Abschnitt 2 nicht auf P_abs2(i,:) = P(2,:) + i*(d/pa(2))*rvP(2,:), sondern um r1 versetzt.

Ich verstehe keinen dieser Sätze. Was ist Abbildung 1?

Zitat:
Du möchtest eigentlich nur Punkte in bestimmtem Abstand auf einem Polygonzug verteilen, oder?

Vielleicht wird es klarer, wenn ich den Code poste. Ich habe tagsüber kein Matlab zur Verfügung. Ich probiere es heute Abend und vielleicht wird es klarer, wenn ich den Code gepostet habe. Ich vermute, 5 Zeilen reichen aus um das Problem allgemein zu lösen - falls ich es richtig verstanden habe.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Sascha
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.02.16
Wohnort: Stuttgart
Version: R2015b
     Beitrag Verfasst am: 15.02.2016, 18:36     Titel:
  Antworten mit Zitat      
Hallo Jan,


der Code in Beitrag #1 ist lauffähig.
Wenn den mal laufen lässt, wird der Polygonzug aus der Punktmenge P in rot und die berechneten Punkte mit gleichen Abständen in blau ausgegeben.

Die einzelnen Abstände zwischen den roten Punkten habe ich z.T. auch als Abschnitte bezeichnet, die Abstände zwischen den blauen Punkten als d.
Zugegeben, das ist etwas verwirrend.

Die Abbildungen 1 und 2 sind an Beitrag #5 angehängt, oder wurden sie nicht hochgeladen?
Bei mir werden sie jedenfalls unter dem Beitrag angezeigt.

Zitat:
Vielleicht wird es klarer, wenn ich den Code poste.


ja, ganz bestimmt!


Viele Grüße
Sascha
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 18.02.2016, 09:41     Titel:
  Antworten mit Zitat      
Hallo Sascha,

Der Code hat doch einige Zeilen mehr, da z.B. auch der Sonderfall berücksichtigt werden muss, dass der letzte interpolierte Punkt genau auf dem letztzen Datenpunkt liegt.

Code:
function Q = PointsOnPoly(P, L)
% PointsOnPoly - equidistant points on a polygon
% Q = PointsOnPoly(P, L)
% INPUT:
%   P: [N x W] matrix with N points with W dimensions.
%   L: Scalar value for the Euclidean distance between the output points.
% OUTPUT:
%   Q: [M x W] matrix, where M is the number of interpolated points.
%
% EXAMPLE:
%   P = [3,1; 2,0.5; 0.75,1; 0.5,2; 1.5,4; 5,3.5; 6,2; 3,1];
%   Q = PointsOnPoly(P, 0.2);
%   plot(P(:, 1), P(:, 2), 'b');
%   hold('on');
%   plot(Q(:, 1), Q(:, 2), 'ro');
%
% Author: Jan Simon, Heidelberg, (C) 2016  matlab.2010[AT]n[MINUS]simon[DOT]de
% License: BSD (use/copy/change/redistribute on own risk, mention the author)

% Number of points:
[N, W] = size(P);

% Cumulativ distance between points:
DX      = diff(P, 1);
Dist    = sqrt(sum(DX .* DX, 2));
CumDist = [0; cumsum(Dist, 1)];

% Linear interpolation of indices:
Step  = (0:L:CumDist(N)).';
Stepi = interp1(CumDist, 1:N, Step);
Ti    = floor(Stepi);
Si    = Stepi - Ti;

% Shift frames on boundary:
edge     = (Ti == N);
Ti(edge) = Ti(N) - 1;
Si(edge) = 1;

% Interpolate coordinates:
Si = Si(:, ones(1, W));  % Expand Si
Q  = P(Ti, :) .* (1 - Si) + P(Ti + 1, :) .* Si;
 

Das ist nochnicht ausgiebig getestet. Ich werde noch daran feilen und es wohl im FileExchange zur Verfügung stellen.

Gruß, Jan

Zuletzt bearbeitet von Jan S am 28.02.2016, 15:08, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
Sascha
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 13.02.16
Wohnort: Stuttgart
Version: R2015b
     Beitrag Verfasst am: 19.02.2016, 14:27     Titel:
  Antworten mit Zitat      
Hallo Jan,


habe deine Function getestet und sie läuft wunderbar. RESPEKT!

Es lassen sich im Beispiel mit den 8 Punkten auch Abstände bis L=2,0 eingeben, sodass auch Abschnitte übersprungen werden können.
In meiner Anwendung sind Abstände bis zu L = 24 realisierbar, was völlig ausreichend ist. An dieser Stelle erstmal herzlichsten Dank für deine Mühe!

Jetzt muss ich nur noch die Abstandsberechnung von L zwischen dem letzten Punkt eines Abschnittes und dem ersten Punkt des neuen Abschnittes in deine Funktion bekommen.

Code:
% Variablen Mitternachtsformel a, b, c

a = rvP(2,1).^2 + rvP(2,2).^2;
b = 2.*P(2,1).*rvP(2,1) - 2.*P_end_abs1(1,1).*rvP(2,1) + 2.*P(2,2).*rvP(2,2) - 2.*P_end_abs1(1,2).*rvP(2,2);
c = P(2,1).^2 - 2.*P_end_abs1(1,1).*P(2,1) + P_end_abs1(1,1).^2 + P(2,2).^2 - 2.*P_end_abs1(1,2).*P(2,2) + P_end_abs1(1,2).^2 - d.^2;

% ergibt Bedingung (3)
r1_abs2 = 1/(2*a) * (-b + sqrt(b^2 - 4*a*c));
r2_abs2 = 1/(2*a) * (-b - sqrt(b^2 - 4*a*c));

% (3) in (1) ergibt Koordinatenpunkt P1_abs2
if (0<= r1_abs2) && (r1_abs2 < 1)
    P1_abs2 = P(2,:) + r1_abs2*rvP(2,:);
elseif (0<= r2_abs2) && (r2_abs2 < 1)
    P1_abs2 = P(2,:) + r2_abs2*rvP(2,:);
end


Angenommen Si ist der Startpunkt auf dem neuen Abschnitt 2 mit den Koordinaten (xSi_2, ySi_2) und der letzte Punkt auf dem Abschnitt davor wäre Ti mit (xTi_1, yTi_1).

Der Abstand zwischen den Punkten soll auch L=sqrt((xSi_2 - xTi_1)^2 + (ySi_2 - yTi_1)^2) betragen.

Ich meine damit den Abstand der direkten Verbindung dieser beiden Punkte, ohne über den Eckpunkt des Abschnittes zu gehen (siehe Abb.1 in Beitrag #3).
Die restlichen Punkte sollen wie in deinem Code weiterhin auf dem Polygon bleiben.

Kannst du mir diesbezüglich bitte weiterhelfen?


Danke und viele Grüße
Sascha
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 19.02.2016, 20:47     Titel:
  Antworten mit Zitat      
Hallo Sascha,

Oh, ich verstehe. Die neuen Punkte sollen den bestimmten Abstand haben. Dann war meine Lösung hilfreich dabei herauszufinden, das es so nicht geht. Schade Smile

Ich denke nochmal darüber nach.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
slinshady
Forum-Century

Forum-Century


Beiträge: 115
Anmeldedatum: 12.01.16
Wohnort: ---
Version: R2012b+
     Beitrag Verfasst am: 20.02.2016, 13:59     Titel:
  Antworten mit Zitat      
wäre dies nicht mit fsolve zum beispiel lösbar?


Ich würde als zwei anonyme Gleichungen für das gesuchte x und y den Pythagoras, mit eingesetzter Länge, und die Polynomgleichung angibst.
Allerdings müsstest du irgendetwas schreiben, dass er erkennt, falls er in dem eigenen Polynom zum Beispiel nur einen Punkt hinter dem aktuellen findet im nächsten sucht.

http://de.mathworks.com/help/optim/ug/fsolve.html

Ich hoffe ich habe es einigermaßen verständlich geschrieben.
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 28.02.2016, 15:13     Titel:
  Antworten mit Zitat      
Hallo Sascha,

Das Problem ist nicht trivial. Man bestimmt einen neuen Punkt, indem man um den aktuellen Punkt einen Kreis mit dem gewünschten Radius zieht und den nächsten Schnittpunkt mit dem Polygon wählte. Es kann aber mehrere Schnittpunkte geben, z.B. wenn das Polygon im Zickzack läuft. Die Entscheidung, welchen der Schnittpunkte man dann wählt ist nicht stetig, so dass fsolve im Zweifelsfall daran scheitern kann und wird. Man kann dann denjenige Punkt wählen, der näher an der Distanz ist, wenn man sich auf dem Original-Polygone bewegt. Aber auch das ist leider nicht eindeutig und man benötigt eine Heuristik, für welchen Punkt man sich dann entscheidet. Diese Ausnahmen machen den Code sehr umfangreich, so dass der notwendige Aufwand deutlich das übersteigt, was ich im Forum beantworten kann.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.