GDI-Vector

  • Hallo

    Ich habe ein Problem.
    Für ein Spiel möchte ich zwei Linien zeichnen und an diesen entlang jeweils eine Ellipse entlangfliegenlassen.

    Ich weiß nur nicht, wie ich die einzelnen Punkte der Grade kriege (Die Graden bewegen sich (Startpunkte sind fix - Enpunkte variabel)).
    Einfacher gesagt, möchte ich Ellipsen von einem fixen Startpunkt auf variable Endpunkte in einer graden Flugbahn fliegen lassen.


    Alles in GDI+

    kA wie das geht ?(?(?(

    Hilfe!

  • Den Vektor der entlangzufahrenden Linie normaliseren und dann X und Y Wert des Normalvektors um einen beliebigen Faktor vergrößern oder verkleinern. Dann hast du die X und Y Werte für die Bewegungsgeschwindigkeit.
    Hier mal eine Funktion von mir ;).

    Spoiler anzeigen
    [autoit]

    Func _Vector_NormVector($aV1)
    $i_VLength = Sqrt($aV1[0] * $aV1[0] + $aV1[1] * $aV1[1])
    $aV1[0] = $aV1[0] / $i_VLength
    $aV1[1] = $aV1[1] / $i_VLength
    EndFunc

    [/autoit]


    Vektor muss als Array übergeben werden, aber das kannst du ja auch ändern. :D

  • Hi
    wenn ich das richtig verstanden habe dann willlste eine Ellipse über eine Gerade verschieben, die immer bei z.B (1I1) losgeht und deren endpunkt du festlegen kannst also nehmen wir mal als bsp der Endpunkt soll (2I3) sein.
    Dann machste daraus ne Gleichung und fertig biste:
    y =mx + b
    m = (y2-y1)/(x2-x1)
    b =y1 - m*x1
    ausgerechnet:
    y = 2x -1

    mfg Redclaw

    edit :
    ich bin jetzt mal von der ebene ausgegangen, wenn dus im raum machen willst dann sieh dir mal parameterform und normalenform und sowas an sind auch net schwer.

    2 Mal editiert, zuletzt von Redclaw (21. Dezember 2010 um 18:41)

  • Ist das nicht ein wenig kompliziert für etwas so Simples? Dann wäre ja die Bewegungsgeschwindigkeit ein Problem... Man müsste also damit leben, dass sich die Ellipse dann auf einer schrägen Linie schneller bewegt als auf einer parallel zu einer der Achsen. :S Um das zu umgehen, habe ich ja eine Normalisierung des Vektors vorgeschlagen (also den Vektor auf die Länge 1 bringen, aber die Richtung beibehalten) ;).

  • Das löst eigentlich nur zum Teil mein Problem.
    Ich hab hier dieses Script:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GuiConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GuionEventmode",1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $Width = 800
    $Height = 600

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("Test",$Width,$Height)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hPen = _GDIPlus_PenCreate(0xFFFF0000,5)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $hGraphics)
    Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hFGBitmap = _GDIPlus_BitmapCreateFromGraphics($Width,$Height, $hGraphics)
    Global $hFGBackbuffer = _GDIPlus_ImageGetGraphicsContext($hFGBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $Mouse = GUIGetCursorInfo($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsClear($hFGBackbuffer,0xFFFFFFFF)
    ;~ If $Mouse[2] = 1 Then

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawLine($hFGBackbuffer,0,$Height,$Mouse[0],$Mouse[1],$hPen)
    _GDIPlus_GraphicsDrawLine($hFGBackbuffer,$Width,$Height,$Mouse[0],$Mouse[1],$hPen)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRect($hBackbuffer,$hFGBitmap,0,0,$Width,$Height)
    _GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmap,0,0,$Width,$Height)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_Shutdown()
    Exit
    EndFunc

    [/autoit]

    Wie sollte ich denn jetzt die von euch genannten Tipps da einbauen?
    Mit der linearen Funktionsgleichung ist es gut umsetzbar für den linken Strahl aber nicht für den rechten
    weil der bei ($Width|$Height) anfängt und auf ($Mouse[0]|$Mouse[1]) geht.

    Aber gute Ansätze :thumbup:

  • Zitat

    Mit der linearen Funktionsgleichung ist es gut umsetzbar für den linken Strahl aber nicht für den rechten
    weil der bei ($Width|$Height) anfängt und auf ($Mouse[0]|$Mouse[1]) geht.

    wieso?
    Der Geradengleichung y=mx+b ist es völlig schnurz, welche Koordinaten gewählt werden. Bis auf den Fall, dass delta x = 0 ist (Gerade senkrecht zur x-Achse) sollte es kein Problem geben!

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GuiConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GuionEventmode",1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $Width = 800
    $Height = 600

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("Test",$Width,$Height)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hPen = _GDIPlus_PenCreate(0xFFFF0000,5)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $hGraphics)
    Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hFGBitmap = _GDIPlus_BitmapCreateFromGraphics($Width,$Height, $hGraphics)
    Global $hFGBackbuffer = _GDIPlus_ImageGetGraphicsContext($hFGBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    ;koordinaten der ecken
    $x0=0;links
    $y0=$Height
    $x1=$width;rechts
    $y1=$Height
    $step=5 ;schrittweite der punkte

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $Mouse = GUIGetCursorInfo($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsClear($hFGBackbuffer,0xFFFFFFFF)
    ;~ If $Mouse[2] = 1 Then
    ;links
    $m=($mouse[1]-$y0)/($mouse[0]-$x0)
    $b=$mouse[1]-$m*$mouse[0]
    for $x=$x0 to $mouse[0] step $step
    $y=$m*$x+$b;y-koordinate
    _GDIPlus_GraphicsDrawEllipse($hGraphics, $X, $Y, 2, 2, $hPen)
    next

    [/autoit] [autoit][/autoit] [autoit]

    ;rechts
    $m=($mouse[1]-$y1)/($mouse[0]-$x1)
    $b=$mouse[1]-$m*$mouse[0]
    for $x=$x1 to $mouse[0] step -$step
    $y=$m*$x+$b;y-koordinate
    _GDIPlus_GraphicsDrawEllipse($hGraphics, $X, $Y, 2, 2, $hPen)
    next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ _GDIPlus_GraphicsDrawLine($hFGBackbuffer,0,$Height,$Mouse[0],$Mouse[1],$hPen)
    ;~ _GDIPlus_GraphicsDrawLine($hFGBackbuffer,$Width,$Height,$Mouse[0],$Mouse[1],$hPen)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRect($hBackbuffer,$hFGBitmap,0,0,$Width,$Height)
    _GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmap,0,0,$Width,$Height)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_Shutdown()
    Exit
    EndFunc

    [/autoit]
  • Sorry, aber ich musste meine Methode jetzt einfach ausprobieren ^^. Und sie funktioniert sogar :P.

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    $iGUIColorBG = 0xFFFFFFFF
    $iGUIWidth = 400
    $iGUIHeight = 400
    $FPS = 40

    [/autoit] [autoit][/autoit] [autoit]

    $iX_LineP1 = $iGUIWidth / 2
    $iY_LineP1 = $iGUIHeight / 2
    $iX_LineP2 = 350
    $iY_LineP2 = 300

    [/autoit] [autoit][/autoit] [autoit]

    $iX_Ellipse = $iX_LineP1
    $iY_Ellipse = $iY_LineP1
    $iSize_Ellipse = 50
    $iSpeedEllipse = 5

    [/autoit] [autoit][/autoit] [autoit]

    $aV_Line = _Vector_Create($iX_LineP2 - $iX_LineP1, $iY_LineP2 - $iY_LineP1)
    $aV_LineNorm = _Vector_NormVector($aV_Line)

    [/autoit] [autoit][/autoit] [autoit]

    $iX_SpeedEllipse = $aV_LineNorm[0] * $iSpeedEllipse
    $iY_SpeedEllipse = $aV_LineNorm[1] * $iSpeedEllipse

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("Example by name22 (autoit.de)", $iGUIWidth, $iGUIHeight)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iGUIWidth, $iGUIHeight, $hGraphic)
    $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)

    [/autoit] [autoit][/autoit] [autoit]

    $hBrush_Ellipse = _GDIPlus_BrushCreateSolid(0xFF0000FF)
    $hPen_Line = _GDIPlus_PenCreate(0xFFFF0000, 2)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    AdlibRegister("_Draw", 1000 / $FPS)

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(1000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Draw()
    $iX_Ellipse += $iX_SpeedEllipse
    $iY_Ellipse += $iY_SpeedEllipse

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsClear($hBuffer, $iGUIColorBG)
    _GDIPlus_GraphicsDrawLine($hBuffer, $iX_LineP1, $iY_LineP1, $iX_LineP2, $iY_LineP2, $hPen_Line)
    _GDIPlus_GraphicsFillEllipse($hBuffer, $iX_Ellipse - $iSize_Ellipse / 2, $iY_Ellipse - $iSize_Ellipse / 2, $iSize_Ellipse, $iSize_Ellipse, $hBrush_Ellipse)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iGUIWidth, $iGUIHeight)
    EndFunc ;==>_Draw

    [/autoit] [autoit][/autoit] [autoit]

    Func _Vector_NormVector($aV1)
    $i_VLength = Sqrt($aV1[0] * $aV1[0] + $aV1[1] * $aV1[1])
    $aV1[0] = $aV1[0] / $i_VLength
    $aV1[1] = $aV1[1] / $i_VLength

    [/autoit] [autoit][/autoit] [autoit]

    Return $aV1
    EndFunc ;==>_Vector_NormVector

    [/autoit] [autoit][/autoit] [autoit]

    Func _Vector_Create($aV_X, $aV_Y)
    Local $aV[2]
    $aV[0] = $aV_X
    $aV[1] = $aV_Y

    [/autoit] [autoit][/autoit] [autoit]

    Return $aV
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hBuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BrushDispose($hBrush_Ellipse)
    _GDIPlus_PenDispose($hPen_Line)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]