Что нового

[Script] Пример построения графиков функций из массива

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
AutoIt: 3.3.2.0
Версия: N/A

Категория: Графика/GDI+, Математика

Описание: Простой пример построения графиков функций из заранее подготовленного 2D массива. Этот код не является полноценной программой, просто пример. Меня недавно спрашивали, как строить графики по заданным точкам. Вот ответ на этот вопрос. Если кого заинтерисовало, то можете использовать представленный ниже код по своему усмотрению.

Код/Пример:
Код:
#Include <GDIPlus.au3>
#Include <GUIConstantsEx.au3>
#Include <Math.au3>
#Include <WinAPI.au3>

Opt('MustDeclareVars', 1)

Dim $aPoints[300][2]

For $i = 0 To UBound($aPoints) - 1
    $aPoints[$i][0] = ($i - 150) / 1.7
    $aPoints[$i][1] = 20 * Sin($aPoints[$i][0] / 20) * Sin($aPoints[$i][0] / 2)
Next

_ViewGraph($aPoints)

Func _ViewGraph($aPoints)

    Local $hForm, $Pic, $hPic
    Local $Scale, $Xi, $Yi, $Xp, $Yp, $XOffset, $YOffset, $Xmin = $aPoints[0][0], $Ymin = $aPoints[0][1], $Xmax = $Xmin, $Ymax = $Ymin
    Local $hBitmap, $hObj, $hGraphic, $hImage, $hBrush, $hPen

    For $i = 1 To UBound($aPoints) - 1
        If $aPoints[$i][0] < $Xmin Then
            $Xmin = $aPoints[$i][0]
        Else
            If $aPoints[$i][0] > $Xmax Then
                $Xmax = $aPoints[$i][0]
            EndIf
        EndIf
        If $aPoints[$i][1] < $Ymin Then
            $Ymin = $aPoints[$i][1]
        Else
            If $aPoints[$i][1] > $Ymax Then
                $Ymax = $aPoints[$i][1]
            EndIf
        EndIf
    Next

    $Scale = 600 / _Max($Xmax - $Xmin, $Ymax - $Ymin)
    $XOffset = Floor(($Xmin + $Xmax) * $Scale / 2)
    $YOffset = Floor(($Ymin + $Ymax) * $Scale / 2)

    _GDIPlus_Startup()
    $hBitmap = _WinAPI_CreateBitmap(601, 601, 1, 32)
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    _WinAPI_DeleteObject($hBitmap)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $hPen = _GDIPlus_PenCreate(0xFFFF0000)
    _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, 601, 601, $hBrush)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
    If Abs($XOffset) <= 300 Then
        _GDIPlus_GraphicsDrawLine($hGraphic, 300 - $XOffset, 0, 300 - $XOffset, 601, $hPen)
    EndIf
    If Abs($YOffset) <= 300 Then
        _GDIPlus_GraphicsDrawLine($hGraphic, 0, 300 + $YOffset, 601, 300 + $YOffset, $hPen)
    EndIf
    _GDIPlus_PenDispose($hPen)
    $hPen = _GDIPlus_PenCreate(0xFF000000)
    For $i = 0 To UBound($aPoints) - 1
        $Xi = 300 - $XOffset + $Scale * $aPoints[$i][0]
        $Yi = 300 + $YOffset - $Scale * $aPoints[$i][1]
        If $i Then
            _GDIPlus_GraphicsDrawLine($hGraphic, $Xp, $Yp, $Xi, $Yi, $hPen)
        EndIf
        $Xp = $Xi
        $Yp = $Yi
    Next
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_Shutdown()

    $hForm = GUICreate('My Graph', 601, 601)
    $Pic = GUICtrlCreatePic('', 0, 0, 601, 601)
    $hPic = GUICtrlGetHandle(-1)

    _WinAPI_DeleteObject(_SendMessage($hPic, 0x0172, 0, $hBitmap))
    $hObj = _SendMessage($hPic, 0x0173)
    If $hObj <> $hBitmap Then
        _WinAPI_DeleteObject($hBitmap)
    EndIf

    GUISetState(@SW_SHOW, $hForm)

    Do
    Until GUIGetMsg() = -3

    GUIDelete($hForm)

EndFunc   ;==>_ViewGraph

Скриншот:



Автор: Yashied
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Yashied
Большое вам спасибо!
Буквально недавно был озадачен подобным вопросом! :ok:
 

11exx

Новичок
Сообщения
24
Репутация
3
Подскажите какой параметр нужно изменить, чтобы график отрисовывался той длины, которая потребуется. В идеале нужно окно с горизонтальной полосой прокрутки. Просто график очень протяжённый нужно отобразить с приемлемым масштабом.
 
Верх