Jump to content

Recommended Posts

Posted (edited)

I am working on an addon to my triangle solver. The triangle that you make will appear to scale at the bottom of the window. I have the function that constructs the triangle finished (but very messy). I am using double buffering based off this template. I think I followed it, but the image isn't clearing so I can view just a single triangle. There should only be one triangle on the screen at a time. Did I use _GDIPlus_GraphicsClear() wrong?

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <Math.au3>

Global Const $GUIWidth = 382
Global Const $GUIHeight = 467
Global $graphics, $bitmap, $backbuffer, $hPenBlack, $hPenRed, $PenWidth = 5
Global $GlobalATop, $GlobalAWidth, $GlobalAXValue, $GlobalAWidth
Global $GlobalBTop, $GlobalBWidth, $GlobalBXValue, $GlobalBWidth
Global $GlobalCTop, $GlobalCWidth, $GlobalCXValue, $GlobalCWidth
Global $GlobalSide1
Global $GlobalSide2
Global $GlobalSide3
Global $GlobalAngle1
Global $GlobalAngle2
Global $GlobalAngle3
Global $GlobalTriangleHeight
Global $GlobalTriangleWidth
Global $GlobalBottom
Global $GlobalLeft
Global $GlobalSide3Inside
Global $GlobalRedSide
Dim $Points1[5][2], $Points2[5][2], $Points3[5][2]

Opt("GUIOnEventMode", 1)
$GUI = GUICreate("Triangle Solver", $GUIWidth, $GUIHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")

#Region Triangle Group
GUICtrlCreateGroup("Reference Triangle", 15, 208, 351, 193)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetColor(-1, 0x0077CC)
#EndRegion Triangle Group

GUISetState()

StartupDrawing($GUI)

DrawTriangle(500, 700, 400, 3)
Sleep(5000)
DrawTriangle(500, 700, 600, 3)
Sleep(5000)

Func Close()
    Exit
EndFunc   ;==>Close

Func StartupDrawing($hWnd)
    _GDIPlus_Startup()
    $graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $bitmap = _GDIPlus_BitmapCreateFromGraphics($GUIWidth, $GUIHeight, $graphics)
    $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
    $hPenBlack = _GDIPlus_BrushCreateSolid(0xFF000000)
    $hPenRed = _GDIPlus_BrushCreateSolid(0xFFFF0000)
EndFunc   ;==>StartupDrawing

Func OnAutoItExit()
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_BrushDispose($hPenBlack)
    _GDIPlus_BrushDispose($hPenRed)
    _GDIPlus_Shutdown()
EndFunc   ;==>OnAutoItExit

Func RePaintTriangle() ;refresh gui with same triangle already present (same effect as DrawTriangle, but faster)
    _GDIPlus_GraphicsClear($backbuffer, 0x00F7F7F7)

    ;setup variables for side letters
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 14, 1)

    If $GlobalRedSide = 1 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points1, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points1, $hPenBlack)
    EndIf

    If $GlobalRedSide = 2 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points2, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points2, $hPenBlack)
    EndIf

    If $GlobalRedSide = 3 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points3, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points3, $hPenBlack)
    EndIf

    #Region Create Angle Letters
    $tLayout = _GDIPlus_RectFCreate($GlobalAXValue, $GlobalATop, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "a", $hFont, $tLayout, $hFormat)
    If $GlobalRedSide = 1 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "a", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "a", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf

    $tLayout = _GDIPlus_RectFCreate($GlobalBXValue, $GlobalBTop, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "b", $hFont, $tLayout, $hFormat)
    If $GlobalRedSide = 2 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "b", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "b", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf

    $tLayout = _GDIPlus_RectFCreate($GlobalCXValue, $GlobalCTop, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "C", $hFont, $tLayout, $hFormat)
    If $GlobalRedSide = 3 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "C", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "C", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf
    #EndRegion Create Angle Letters

    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $GUIWidth, $GUIHeight)
EndFunc   ;==>RePaintTriangle

Func DrawTriangle($iSide1, $iSide2, $iSide3, $iRedSide = 0)
    Local $Angle1, $Angle2, $Angle3
    Local $Pi = 3.141592654

    _GDIPlus_GraphicsClear($backbuffer, 0x00F7F7F7)

    ;setup variables for side letters
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 14, 1)

    $Angle1 = ACos(($iSide2 ^ 2 + $iSide3 ^ 2 - $iSide1 ^ 2) / (2 * $iSide2 * $iSide3));law of cosines
    $Angle2 = ACos(($iSide1 ^ 2 + $iSide3 ^ 2 - $iSide2 ^ 2) / (2 * $iSide1 * $iSide3));law of cosines
    $Angle3 = $Pi - $Angle1 - $Angle2

    ;Calculate height using Heron's Formula
    $s = ($iSide1 + $iSide2 + $iSide3) / 2
    $A = Sqrt($s * ($s - $iSide1) * ($s - $iSide2) * ($s - $iSide3))
    $TriangleHeight = (2 * $A) / $iSide1
    If _Degree($Angle2) > 90 Then
        $TriangleWidth = $iSide2 * Cos($Angle3)
    ElseIf _Degree($Angle3) > 90 Then
        $TriangleWidth = $iSide3 * Cos($Angle2)
    Else
        If $iSide1 > ($iSide2 And $iSide3) Then
            $TriangleWidth = $iSide1
        ElseIf $iSide2 > ($iSide1 And $iSide3) Then
            $TriangleWidth = $iSide2
        Else
            $TriangleWidth = $iSide3
        EndIf
    EndIf

    If $TriangleHeight > 140 Or $TriangleWidth > 340 Then
        Do
            $iSide1 *= 0.95
            $iSide2 *= 0.95
            $iSide3 *= 0.95

            $s = ($iSide1 + $iSide2 + $iSide3) / 2
            $A = Sqrt($s * ($s - $iSide1) * ($s - $iSide2) * ($s - $iSide3))
            $TriangleHeight = (2 * $A) / $iSide1
            If _Degree($Angle2) > 90 Then
                $TriangleWidth = $iSide2 * Cos($Angle3)
            ElseIf _Degree($Angle3) > 90 Then
                $TriangleWidth = $iSide3 * Cos($Angle2)
            Else
                If $iSide1 > ($iSide2 And $iSide3) Then
                    $TriangleWidth = $iSide1
                ElseIf $iSide2 > ($iSide1 And $iSide3) Then
                    $TriangleWidth = $iSide2
                Else
                    $TriangleWidth = $iSide3
                EndIf
            EndIf
        Until $TriangleHeight <= 140 And $TriangleWidth <= 340
    Else
        If $TriangleHeight * 1.05 < 140 And $TriangleWidth * 1.05 < 340 Then
            Do
                $iSide1 *= 1.05
                $iSide2 *= 1.05
                $iSide3 *= 1.05

                $s = ($iSide1 + $iSide2 + $iSide3) / 2
                $A = Sqrt($s * ($s - $iSide1) * ($s - $iSide2) * ($s - $iSide3))
                $TriangleHeight = (2 * $A) / $iSide1
                If _Degree($Angle2) > 90 Then
                    $TriangleWidth = $iSide2 * Cos($Angle3)
                ElseIf _Degree($Angle3) > 90 Then
                    $TriangleWidth = $iSide3 * Cos($Angle2)
                Else
                    If $iSide1 > ($iSide2 And $iSide3) Then
                        $TriangleWidth = $iSide1
                    ElseIf $iSide2 > ($iSide1 And $iSide3) Then
                        $TriangleWidth = $iSide2
                    Else
                        $TriangleWidth = $iSide3
                    EndIf
                EndIf
            Until $TriangleHeight * 1.05 >= 140 Or $TriangleWidth * 1.05 >= 340
        EndIf
    EndIf

    $Bottom = (208 + 5) + ((193 - $TriangleHeight) / 2) + $TriangleHeight
    $Left = 15 + ((351 - $TriangleWidth) / 2)
    If _Degree($Angle2) > 90 Then $Left += $iSide3 * Cos(_Radian(180 - _Degree($Angle2)))

    $iSide3Inside = $iSide3 - ($PenWidth / Tan($Angle2 / 2)) - ($PenWidth / Tan($Angle1 / 2))

    $Points1[0][0] = 4
    $Points1[0][1] = 0
    $Points1[1][0] = $Left
    $Points1[1][1] = $Bottom
    $Points1[2][0] = $Left + ($PenWidth / Tan($Angle2 / 2))
    $Points1[2][1] = $Bottom - $PenWidth
    $Points1[3][0] = $Left + $iSide1 - ($PenWidth / Tan($Angle3 / 2))
    $Points1[3][1] = $Bottom - $PenWidth
    $Points1[4][0] = $Points1[1][0] + $iSide1
    $Points1[4][1] = $Bottom
    If $iRedSide = 1 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points1, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points1, $hPenBlack)
    EndIf

    $Points2[0][0] = 4
    $Points2[0][1] = 0
    $Points2[1][0] = $Points1[3][0]
    $Points2[1][1] = $Points1[3][1]
    $Points2[2][0] = $Points1[4][0]
    $Points2[2][1] = $Points1[4][1]
    $Points2[3][0] = $Left + ($iSide3 * Cos($Angle2))
    $Points2[3][1] = $Bottom - ($iSide3 * Sin($Angle2))
    $Points2[4][0] = $Points1[2][0] + ($iSide3Inside * Cos($Angle2))
    $Points2[4][1] = $Points1[2][1] - ($iSide3Inside * Sin($Angle2))
    If $iRedSide = 2 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points2, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points2, $hPenBlack)
    EndIf

    $Points3[0][0] = 4
    $Points3[0][1] = 0
    $Points3[1][0] = $Points2[3][0]
    $Points3[1][1] = $Points2[3][1]
    $Points3[2][0] = $Points2[4][0]
    $Points3[2][1] = $Points2[4][1]
    $Points3[4][0] = $Points1[1][0]
    $Points3[4][1] = $Points1[1][1]
    $Points3[3][0] = $Points1[2][0]
    $Points3[3][1] = $Points1[2][1]
    If $iRedSide = 3 Then
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points3, $hPenRed)
    Else
        _GDIPlus_GraphicsFillPolygon($backbuffer, $Points3, $hPenBlack)
    EndIf

    #Region Create Angle Letters
    ;temperary to test for rectangle width
    $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "a", $hFont, $tLayout, $hFormat)
    $GlobalAWidth = DllStructGetData($aInfo[0], "Width")
    $GlobalAHeight = DllStructGetData($aInfo[0], "Height")
    $GlobalATop = $Points1[1][1] - 3

    $GlobalAXValue = $Points1[1][0] + ($iSide1 / 2) - ($GlobalAWidth / 2)
    $tLayout = _GDIPlus_RectFCreate($GlobalAXValue, $GlobalATop, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "a", $hFont, $tLayout, $hFormat)
    If $iRedSide = 1 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "a", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "a", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf

    ;temperary to test for rectangle width
    $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "b", $hFont, $tLayout, $hFormat)
    $GlobalBWidth = Int(DllStructGetData($aInfo[0], "Width") + 1)
    $GlobalBHeight = Int(DllStructGetData($aInfo[0], "Height") + 1)
    $GlobalBTop = $Bottom - ($TriangleHeight / 2) - ($GlobalBHeight / 2)

    If _Degree($Angle3) > 90 Then
        $GlobalBXValue = $Points2[2][0] + (($Points2[3][0] - $Points2[2][0]) / 2) + 3
    Else
        $GlobalBXValue = $Points2[2][0] + (($Points2[3][0] - $Points2[2][0]) / 2) + ($GlobalBWidth / 2)
    EndIf

    $tLayout = _GDIPlus_RectFCreate($GlobalBXValue, $GlobalBTop, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "b", $hFont, $tLayout, $hFormat)
    If $iRedSide = 2 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "b", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "b", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf

    ;temperary to test for rectangle width
    $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "C", $hFont, $tLayout, $hFormat)
    $GlobalCWidth = Int(DllStructGetData($aInfo[0], "Width") + 1)
    $GlobalCHeight = Int(DllStructGetData($aInfo[0], "Height") + 1)
    $GlobalCTop = $Bottom - ($TriangleHeight / 2) - ($GlobalCHeight / 2)

    If _Degree($Angle2) > 90 Then
        $GlobalCXValue = $Points2[3][0] + (($Points1[1][0] - $Points2[3][0]) / 2) - $GlobalCWidth
    Else
        $GlobalCXValue = $Points2[3][0] + (($Points1[1][0] - $Points2[3][0]) / 2) - $GlobalCWidth - 3
    EndIf
    $tLayout = _GDIPlus_RectFCreate($GlobalCXValue, $GlobalCTop, 0, 0)

    $aInfo = _GDIPlus_GraphicsMeasureString($backbuffer, "C", $hFont, $tLayout, $hFormat)
    If $iRedSide = 3 Then
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "C", $hFont, $aInfo[0], $hFormat, $hPenRed)
    Else
        _GDIPlus_GraphicsDrawStringEx($backbuffer, "C", $hFont, $aInfo[0], $hFormat, $hPenBlack)
    EndIf
    #EndRegion Create Angle Letters

    $GlobalSide1 = $iSide1
    $GlobalSide2 = $iSide2
    $GlobalSide3 = $iSide3
    $GlobalAngle1 = $Angle1
    $GlobalAngle2 = $Angle2
    $GlobalAngle3 = $Angle3
    $GlobalTriangleHeight = $TriangleHeight
    $GlobalTriangleWidth = $TriangleWidth
    $GlobalBottom = $Bottom
    $GlobalLeft = $Left
    $GlobalSide3Inside = $iSide3Inside
    $GlobalRedSide = $iRedSide

    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $GUIWidth, $GUIHeight)

EndFunc   ;==>DrawTriangle
Edited by dantay9
Posted (edited)

Gotta love that template. It has spread pretty good :)

massive code, but this:

_GDIPlus_GraphicsClear($backbuffer, 0x00F7F7F7)

Won't clear anything since you have specified 00 as the alpha channel. Example: 0xFFFF0000 will be 100% red, 0x7FFF0000 will be 50% and 0x00FF0000 is 0%.

Edited by monoceres

Broken link? PM me and I'll send you the file!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...