Objekte auf bestimmter Strecke anordnen

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

M0rgenstern

Betreff: Objekte auf bestimmter Strecke anordnen

BeitragSa, Apr 03, 2010 18:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey Leute.
Entschuldigung, wenn ich im falschen Themenbereich bin, aber ich weiß echt nicht wo dieses Anliegen hingehört.
Es geht weniger um den Code an sich, sondern eher um die Technik/Mathematik bei folgendem Problem:

Ich habe eine Linie, die sagen wir mit der Maus gezogen wird.
Jetzt will ich bestimmte Objekte (Vierecke), die alle die gleiche Breite und Höhe haben, in einem bestimmten Abstand hintereinander auf dieser Linie verteilen.
Mein Problem ist nun: Wie berechne ich die Koordinaten der einzelnen Objekte?
Ich glaube, dass man dazu Vektoren bräuchte, aber damit kenn ich mich leider absolut (noch) nicht aus.
Bin mir aber nicht sicher ob ich das bräuchte, wüsste aber auch nicht wie man es sonst machen könnte.

Hat jemand von euch vielleicht ne Idee?

Lg, M0rgenstern
 

Lion

BeitragSa, Apr 03, 2010 18:38
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]
Graphics 800, 600, 0, 50

Const Breite:Int = 60
Const abstand:Int = 20
Const hoehe:Int = 60

DrawLine 0, 400, 800, 400

For Local i:Int = 0 To GraphicsWidth() / (Breite + abstand)
DrawRect(i * (Breite + abstand), 400 - hoehe-1, Breite, hoehe)
Next

Flip
WaitKey()


Ich glaub, ich hab das problem nicht verstanden? o.O
Intel Core 2 Quad 4x2.66 ghz - 4gb ddr2 - nvidia GeForce GTX660 2gb
Intel Atom 1x1.83 ghz - 2gb ddr2 - intel GMA 3150 256mb
AMD A10-5750M 4x2.5 ghz - 8 gb ddr4 - AMD R9 M290x

The Shark

BeitragSa, Apr 03, 2010 18:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Da gibts mehere möglichkeiten:

1. abstand und winkel berechnen und dann mit sinus/cosinus punkte bestimmen
2. Gerade durchlegen, d.h.
- Steigung berechnen
- C Bestimmen (m*x+c)
- horizontaler unterschied bestimmen
- bei den stellen y-position ausrechnen
3. horizontaler und vertikaler abstand ausrechnen und einteilen <- am schnellsten
  • Zuletzt bearbeitet von The Shark am Sa, Apr 03, 2010 18:40, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragSa, Apr 03, 2010 18:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Winkel von Startpunkt bis Endpunkt der Linie mit Atan2 berechnen.
x = StartX + cos(winkel) * Abstand
y = StartY - sin(winkel) * Abstand
Wobei du Abstand mit jedem Objekt um einen festen Wert erhöhst.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

DaysShadow

BeitragSa, Apr 03, 2010 19:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit Vektoren:

BlitzMax: [AUSKLAPPEN]
SuperStrict

Type TVector2f

Field _x:Float
Field _y:Float
Field _nx:Float
Field _ny:Float
Field _length:Float

Method Init:TVector2f( x:Float, y:Float )

_x = x
_y = y
_length = GetLength( )
Normalize( )

Return Self

End Method

Method GetLength:Float( )

Return Sqr( ( _x * _x ) + ( _y * _y ) )

End Method

Method Normalize:Int( )

_nx = ( ( 1.0 / _length ) * _x )
_ny = ( ( 1.0 / _length ) * _y )

End Method

Method GetX:Float( )

Return _x

End Method

Method GetNX:Float( )

Return _nx

End Method

Method SetX:Float( x:Float )

_x = x

End Method

Method GetY:Float( )

Return _y

End Method

Method GetNY:Float( )

Return _ny

End Method

Method SetY:Float( y:Float )

_y = y

End Method

End Type

Graphics( 800, 600, 0, 60 )

Global a:TVector2f = New TVector2f, b:TVector2f = New TVector2f, ab:TVector2f = New TVector2f
Global a_set:Int, b_set:Int

Global quadList:TList = CreateList( )

Repeat

Cls( )

If( KeyHit( KEY_DELETE ) )

a_set = False
b_set = False
quadList.Clear( )

End If

If( MouseHit( MOUSE_LEFT ) )

If( Not( a_set ) )

a.Init( MouseX( ), MouseY( ) )

a_set = True

Else

b.Init( MouseX( ), MouseY( ) )

ab.Init( b.GetX( ) - a.GetX( ), b.GetY( ) - a.GetY( ) )

For Local i:Int = 0 To ab.GetLength( ) Step 20

quadList.AddLast( New TVector2f.Init( a.GetX( ) + i * ab.GetNX( ), a.GetY( ) + i * ab.GetNY( ) ) )

Next

b_set = True

End If

End If

If( a_set And b_set )

DrawLine( a.GetX( ), a.GetY( ), b.GetX( ), b.GetY( ) )

For Local vec:TVector2f = EachIn quadList

DrawRect( vec.GetX( ) - 2.5, vec.GetY( ) - 2.5, 5, 5 )

Next

End If

Flip( )

Until KeyHit( KEY_ESCAPE ) Or AppTerminate( )


Ist vielleicht schwieriger zu verstehen, allerdings empfinde ich die Vektorenvariante meistens als einfacher nachzuvollziehen.
Es lohnt sich jedenfalls sich mit Vektoren anzufreunden Wink

In der For-Schleife mit Step 20 kannst du die Abstände einstellen, statt 20 halt 50 oder sonstwas schreiben.

MfG DaysShadow
Blessed is the mind too small for doubt

M0rgenstern

BeitragSo, Apr 04, 2010 9:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, vielen Dank für die schnellen Antworten.

Ich hab das ganze mit Sinus und Cosinus jetzt versucht in Code umzusetzen, funktioniert aber noch nicht ganz, da ich mit dem ATAN2 einfach nicht klar komme.

Ich hab hier mal den Code der Funktion:

BlitzMax: [AUSKLAPPEN]
Function Line(x:Int, y:Int, Firstx:Int, Firsty:Int, choosenButton:TButton)
Local Winkel:Int
Local Length:Int
Local Abstand:Int = 15
Local Diagonale:Int = 45
Local Gesamt:Int = Abstand + Diagonale
Local Anzahl:Int

SetColor choosenButton.ired, choosenButton.igreen, choosenButton.iblue
DrawLine(Firstx, Firsty, x, y)
Length = Pythagoras(Firstx, Firsty, x, y)
Winkel = ATan2(y - Firsty, x - Firstx)
Anzahl = Length / Gesamt
For Local index:Int = 1 To Anzahl
Local BrickX:Int, BrickY:Int
BrickX = Firstx + Cos(Winkel) * index
BrickY = Firsty - Sin(Winkel) * index
DrawImage(tibrick, BrickX, BrickY)
Next

SetColor 255, 255, 255
End Function


@DaysShadow:
Ich würde mich sofort mit Vektoren anfreunden, wenn ich das ganze verstehen würde. Das Thema kommt leider erst nächstes Schuljahr und die Leute die ich kenne, die das Thema beherrschen haben sich leider bisher nie die Zeit genommen mir das mal zu erklären.
Sonst würde ich lieber damit arbeiten, weils mir einfacher und felxibler erscheint.

Lg, M0rgenstern
 

n-Halbleiter

BeitragSo, Apr 04, 2010 11:06
Antworten mit Zitat
Benutzer-Profile anzeigen
http://www-e.uni-magdeburg.de/...chnung.pdf hat mir geholfen. Vektoren mögen zu Beginn vielleicht ein wenig komplex anmuten, doch sie sind an sich sehr einfach (vor allem, da man sie sich geometrisch verdeutlichen kann).
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

mpmxyz

BeitragSo, Apr 04, 2010 11:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mal deinen Code korrigiert und ein kleines Testprogramm dazu erstellt:
BlitzMax: [AUSKLAPPEN]
SuperStrict
Graphics 800,600,0

Local x:Int
Local y:Int
Repeat
Cls
If MouseDown(MOUSE_LEFT)
x=MouseX()
Y=MouseY()
EndIf
Line(x,y,MouseX(),MouseY())
Flip
Until KeyHit(KEY_ESCAPE)


Function Line(x:Int, y:Int, Firstx:Int, Firsty:Int)
Local Winkel:Float
Local Length:Float
Local Abstand:Int = 15
Local Diagonale:Int = 45
Local Gesamt:Int = Abstand + Diagonale
Local Anzahl:Int

DrawLine(Firstx, Firsty, x, y)
Length = Sqr((Firstx-x)*(FIrstX-x)+(Firsty-y)*(Firsty-y))
Winkel = ATan2(y - Firsty, x - Firstx)
Anzahl = Length / Gesamt
For Local index:Int = 1 To Anzahl
Local BrickX:Int, BrickY:Int
BrickX = Firstx + Cos(Winkel) * index * (Length/Anzahl)
BrickY = Firsty + Sin(Winkel) * index * (Length/Anzahl)
DrawRect(BrickX-5, BrickY-5,10,10)
Next

SetColor 255, 255, 255
End Function

Ein paar Teile hatte ich wegnehmen/ändern müssen, damit der Code bei mir funktioniert.
Es waren nur drei kleine Fehler drin:
1. Die y-Richtung war gespiegelt
2. Du hast vergessen, die "Linienbewegung" mit einem Faktor, der von der Länge der Stecke abhängig ist, zu multiplizieren.
3. Länge und Richtung mussten wegen sonst entstehenden Ungenauigkeiten zu Floats werden.

Zu den Vektoren:
n-halbleiter scheint eine gute Seite gefunden zu haben.
Falls allerdings Fragen bestehen, gehöre ich zu denen, die Zeit haben. Smile
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragSo, Apr 04, 2010 15:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Also.
@mpmxyz:
Ich hab jetzt mal meinen Code umgeschrieben und das ganze funktioniert ausgezeichnet. Natürlich ist der Code momentan relativ schlecht strukturiert, ich muss das alles nochmal sauber schreiben.
Vielen Dank.

Aber:
Das mit den Vektoren hab ich mir jetzt mal in den Kopf gedonnert.
Ich peils trotzdem nicht. Ich habs soweit verstanden, dass ein Vektor eine Verschiebung angiebt. Also z.B. bei zwei Punkten gibt der Vektor an wie der eine Punkt zum anderen verschoben ist.
WEnn man Vektoren gegeneinander aufaddiert erhält man einen neuen Vektor der eine neue Verschiebung angiebt.
Das hab ich verstanden. Aber weiter komm ich auch nicht. Ich wüsste auch nicht, wie ich mit dem ganzen Zeug rechnen sollte. Wenn ich z.b. ein Koordinatensystem habe und da die Verschiebung von Punkten berechnen sollte.
Dann müsste man ja eigentlich die XKoordinate des einen Punktes von der XKoorinate des anderen Punktes subtrahieren, das mal i rechnen (wobei ich nicht verstehe was genau i bzw. j ist), das gleiche mit den y-Koordinaten und j machen und das ganze addieren.
Aber was wäre das Ergebnis? Also, dann bekommt man ein Ergebnis raus und weiß nun was genau?
Und wie das ganze dann für mathematische Probleme in Code umzusetzen wäre ist mir auch noch ein Rätsel.

Lg, M0rgenstern

mpmxyz

BeitragSo, Apr 04, 2010 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, der Teil ist ein bischen umständlich formuliert.
Der Vektor i ist der Vektor der x-Achse und der Vektor j ist der der y-Achse.
(Die mathematische Sprache neigt teilweise dazu, etwas umständlich zu werden. Razz)

Unterm Strich wird der Vektor in verschiedene Teile, die Komponenten, aufgeteilt.
Diese Komponenten sind nun nicht mehr Vektoren sondern nur noch einfache Zahlen.
Der dreidimensionale Vektor A lässt sich z.B. so schreiben: (Ax|Ay|Az)
Die Berechnungen in der Komponentendarstellungen sind dann die, mit denen man dann programmiert.

Das sollte dir beim Weiterlesen helfen.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragSo, Apr 04, 2010 20:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm...
Also, ich fasse mal zusammen wie weit ich jetzt mit meinem Verständnis bin:
Wenn ich einen Punkt, sagen wir A, mit den Koordinaten (5/8) und einen Punkt B mit den Koordinaten (7/10) habe und den Vektor zwischen diesen beiden Punkten berechnen will, dann muss ich folgendes rechnen:
Ortsvektor B- Ortsektor A = Vektor c. Und da der Ortsvekter von A und B die gleichen Koordinaten hat wie jeweils die Punkte kann man die übernehmen. Explizit muss man also rechnen: (7-5)*i+(10-8)*j = Vektor c
Hier habe ich immernoch das Problem: i und j sind die Vektoren der Achsen. Aber welchen Wert haben die? Ich habe gelesen, dass die den Wert 1 haben, aber warum dann noch in die Rechnung miteinbeziehen?
Dann habe ich den Vektor c mit (2/2).
Die Länge davon kann man dann folgendermaßen berechnen: Pythagoras auf die Komponenten anwenden, also:
sqrt(2²+2²) = Verktorlänge (Hier 2,8).
Für mein oben genanntes Problem müsste ich ja jetzt die Länge Teilen durch die Größe der Objekte samt Abstand.
Also, sagen wir mal so ein Objekt nimmt mit dem "Sicherheitsabstand" insgesamt 0,6 ein, dann müsste ich 2,8/0,6 = 4,7, also 5 Objekte könnte man auf diese Strecke bringen.

Und hier fangen dann meine Probleme wieder an.
Ich hab mir überlegt, dass man nun den Vektor c durch die Anzahl der Objekte teilen müsste, das wäre dann im Ergebnis (0,4/0,4).
Und dann multipliziert man die Objektnummer mit diesem Ergebnis und Multipliziert dies zum Ortsvektor von Punkt A.
Also Für Objekt 2 z.b.: (0,4/0,4) * 2 = (0,8/0,8) -> (0,8/0,8) * (5/8) = (4/6,4)
Wir ihr seht wären die Koordinaten nun aber vollkommener Blödsinn.

Ich komme also wieder nich weiter und den letzten Teil hab ich mir auch nur irgendwie zusammengereimt. Also, bei der Sache mit der Länge bin ich mir noch sicher und dass man diese durch die Größe der Objekte teilen muss auch. Weiter komm ich aber nicht.

Tut mir leid, wenn ich euch so damit belämmer, aber ich werde aus der PDF Datei nicht 100%ig schlau, bin aber wenigstens schonmal ein wenig vertrauter mit der ganzen Sache.

Lg, M0rgenstern

mpmxyz

BeitragSo, Apr 04, 2010 20:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Kurz vor Ende hast du den Fehler eingebaut:
Zitat:
(0,8/0,8) * (5/8)

Wenn man einen Vektor an einen anderen Vektor dransetzen möchte - das möchtest du ja - muss man die Vektoren miteinander addieren.
Eine erklärende Begründung, dass du sie aneinandersetzen musst, fällt mir leider gerade nicht ein; mache dir mal eine kleine Zeichnung.
Zeichnungen kann ich für Problemlösungen übrigens wärmstens empfehlen.
Dann hat man es viel einfacher, eine Lösung auf Vektorbasis zu finden.
Sonst muss ich aber sagen, dass du gut gelernt zu haben scheinst.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragSo, Apr 04, 2010 20:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, vielen Dank.
Natürlich, ist eigentlich total logisch, wenn man das so sieht.
Zu den Zeichnungen: DIe hab ich hier en masse vor mir liegen^^.

Habs jetzt endlich verstanden. Damit lässt sich dann super arbeiten.
Ich glaube, damit kann man viele Probleme sauber und einfach und schnell lösen.

Vielen Dank.

Lg, M0rgenstern

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group