Ich habe einen Punkt 1 gegeben, der von Punkt 2 n einheiten entfernt ist.
Nun brauche ich eine Funktion, die mir alle Punkte in einem array of TPoint zurückgibt, die höchstens n-1 einheiten von Punkt 1 enfernt sind. Ich habe bichts geeignetes finden können. Vielleicht kann mir ja einer von euch da weiterhelfen.
Registriert: So Feb 06, 2005 17:29 Beiträge: 187
Programmiersprache: C, C++
Ich hab mal was überlegt, bin dabei aber auch selbst auf eine Frage gestoßen: Wie regelt man das am besten, wenn eine Funktion ein dynamisches Array zurückgeben soll?
(Falsche Taste gedrückt, unfertiger Beitrag wurde gepostet)
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Zuletzt geändert von Ziz am Mo Jan 30, 2006 20:21, insgesamt 1-mal geändert.
Sprich, du willst alle Punkte auf der Kriesfläche...
Dafür gibts die "Kreisgleichung", die Average Idiot in seinem Code benutzt, aber nicht erklärt hat.
r²=(x-Mx)²+(y-My)²
Mx und My sind dabei die Koordinaten des Mittelpunkts. Hier bitte nciht multiplizieren! ^^
Außerdem sei M der Punkt1 und x und y seien die Koordinaten des Punktes 2, der den Radius errechnen lässt und somit den kreis.
Nun gibt es aber ein Probleme. rein mathematisch gibt es undendlich Punkte, die du suchst. Rein technisch gesehen mit Pixeln rechnend kann man natürlich x Lösungen finden, wobei x Element der natürlichen Zahlen.
Hier wäre mal ein beispielcode, der ungefährt funzen müsste. Nur die Tpointsache müsstes anpassen, da kenn ich mich nich aus:
(Ich kopiere mal das grundgerüst von Average Idiot)
Code:
type TPunkte =record
punkte :arrayof TPoint;
anzahl :longint;
end;
function PunkteInKreis (P1, P2: TPoint): TPunkte;
var n,x,y:integer;
begin
PunkteInKreis.anzahl:=0;
n :=round(sqrt(sqr(P1.x-P2.x)+sqr(P1.y-P2.y)))-1;
for x:=-n to n do
for y:=-n to n do
ifsqr(n)>=sqr(x)+sqr(y)then//Hier wird überprüft, ob ein Punkt mit den koordinaten (x|y) im Radius von n liegt mit dem mittelpunkt (0|0)
begin
inc(PunkteInKreis.anzahl);
PunkteInKreis.punkte[PunkteInKreis.anzahl].x:=x;
PunkteInKreis.punkte[PunkteInKreis.anzahl].y:=y;
end;
end;
Ich weiß nicht, ob es funzt, aber wenn man die kreisgleichung erstmal kapiert hat, dürfte es leicht selbst machbar sein!
mfg Cyberpuer
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Registriert: Mi Dez 15, 2004 20:36 Beiträge: 454 Wohnort: Wien, Österreich
Es sind mir 2 Sachen aufgefallen.
1. IMO wenn es um eine KomplexeDatenstruktur handelt, sollte man es immer über eine VAR(Pointer) Paprameter zurückgeben. So:
Hmm... Davon ausgehend, dass du recht hast, hier der optmierte Code:
Code:
type TPunkte =arrayof TPoint;
procedure PunkteInKreis (P1, P2: TPoint;var result : Tpunkte);
var n,x,y:integer;
begin
n :=round(sqrt(sqr(P1.x-P2.x)+sqr(P1.y-P2.y)))-1;
for x:=-n to n do
for y:=-n to n do
ifsqr(n)>=sqr(x)+sqr(y)then//Hier wird überprüft, ob ein Punkt mit den koordinaten (x|y) im Radius von n liegt mit dem mittelpunkt (0|0)
begin
result.punkte[length(result)+1].x:=x;
result.punkte[length(result)+1].y:=y;
end;
end;
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
sniper hat geschrieben:
Es sind mir 2 Sachen aufgefallen. 1. IMO wenn es um eine KomplexeDatenstruktur handelt, sollte man es immer über eine VAR(Pointer) Paprameter zurückgeben. So:
Also das ist ein Problem, das man prima achteln kann. wenn ein Punkt im ersten Oktant in der Lösungsmenge enthalten ist, dann sind auch alle Spiegelungen dieses Punktes enthalten.
Metacode:
Code:
function AllePunkteImKreis(M,P:TPoint;var Result:Arrayof TPoint)
function Lösung(x,y)
begin
SetLength(Result,length(result+8);
result[Length(result)-8]:=TPoint(M.X+x,M.Y+y);
result[Length(result)-7]:=TPoint(M.X+x,M.Y-y);
result[Length(result)-6]:=TPoint(M.X-x,M.Y-y);
result[Length(result)-5]:=TPoint(M.X-x,M.Y+y);
result[Length(result)-4]:=TPoint(M.X+y,M.Y+x);
result[Length(result)-3]:=TPoint(M.X+y,M.Y-x);
result[Length(result)-2]:=TPoint(M.X-y,M.Y-x);
result[Length(result)-1]:=TPoint(M.X-y,M.Y+x);
end;
begin
SetLength(Result,0);//Array löschen
r:=(P.X-M.X)^2+(P.Y-M.Y)^2;
für alle x von 0 bis (P.X-M.X)
für alle y von 0 bis (P.Y-M.Y)
wenn x^2+y^2<=r
dann Lösung(x,y)
sonst break;//wenn der nicht drin ist, dann auch alle nachfolgenden dieser Schleife
end;
end;
end;
hoffe, das hilft
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Registriert: Mi Aug 17, 2005 13:19 Beiträge: 98 Wohnort: Jahnsdorf
Also zwei Dinge hier mal am Rande:
1. Records und Arrays (genauso wie String) werden von Delphi als Pointer auf die eigentlichen Daten behandelt. Benutzt man kein var wird bei Records und Arrays ein zusätzlicher Platz im Stackframe für die eigentlichen Daten reserviert, der die Daten enthält. Bei Strings wird wie gewohnt ein Pointer auf den String zurückgegeben (der vorher jedoch explizit kopiert wurde).
2. Bei Funktionen ist der Rückgabewert ein impliziter Var-Parameter der Funktion, der an die Argument-Liste angehängt wird. Funktionen sollten daher maximal zwei explizite Parameter haben, wenn man nicht zu viel über den Stack arbeiten will, was durchaus langsam sein kann.
2ct
P.S.: Die Lösung von Sidorion ist soweit vom Ansatz her korrekt, enthält aber folgende Fehler:
1. r muss die Wurzel des Ausdrucks rechts sein.
2. Die Zählvariablen in den Schleifen müssen von 0 bis R-1 laufen
Das mit dem n-1 hatte ich überlesen.. dann muss es aber auch '<r' heissen und nicht '<=r'
Dass r nicht die Wurzel des rechten Ausdrucks ist, ist korrekt, da ich mir dadurch das Wurzelziehen komplett spare. r ist quasi das Quadrat des Radiuses. Wenn Du hier die Wurzel ziehst, musst Du auch in der Schleife bei der Prüfung jedesmal die Qurzel ziehen und das frisst Zeit, bringt aber keine weiteren Erkenntnisse.
a^2 < b^2 <=> a<b (a,b e N).
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Mitglieder in diesem Forum: 0 Mitglieder und 9 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.