Member 10118655 Ответов: 2

Графика в VB 2010.drawline


Я пишу небольшую программу-заставку для рисования линий на экране с помощью таймера.
Для этого из файла считываются две точки данных A &B и вычисляются координаты (x,y) в пикселях для A &B.
Линия от точки А до точки в рисуется с помощью метода graphics. drawline. Пока все работает нормально.
Следующая линия от точки в ДО С рисуется аналогично.
Проблема в том, что при рисовании линии BC линия AB не сохраняется на экране.
Как я могу нарисовать отрезки линий BC, CD, DE и так далее с помощью таймера, сохраняя при этом предыдущие ?
Я использую VB 2010.

По сути, я рисую линию, состоящую из многочисленных сегментов, где каждый сегмент должен быть нарисован с помощью события тика таймера.

Что я уже пробовал:

Я пробовал не использовать "обновить" в timer. tick sub.

вот код

Imports Microsoft.Win32
Imports Microsoft.VisualBasic
Imports System.Math
Imports System.Drawing.Drawing2D

Public Class frmscr
    Dim greenPen2 As New Pen(Color.Green, 5)
    Dim grayPen1 As New Pen(Color.Gray, 1)

    Dim WithEvents tmrClock As New Timer

    Public point1 As New Point
    Public point2 As New Point

    Private Sub frmscr_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'Read input data file,reads array of GR
        Call ReadTxtInputFile()

        'Get screen size in pixels
        scrW = Screen.PrimaryScreen.Bounds.Width.ToString
        scrH = Screen.PrimaryScreen.Bounds.Height.ToString
        Windows.Forms.Cursor.Hide()

        'initialize variable i
        i = 1

        'Compute screen x,y of start point in pixels
        'where xo1p is x offset in pixels
        'gr(0) is 1st point of array
        't1Wp is width of 1st vertical track
        'grmax & grmin are max & min values of parameter array value gr(i)
        xGR0 = xo1p + t1Wp * (GR(0) - GRmin) / (GRmax - GRmin)
        yGR0 = 0

        'set initial values of second point & its backup value
        xGR1 = xGR0
        xGR2 = xGR0
        yGR1 = yGR0
        yGR2 = yGR0


        ' Set Pen Styles
        greenPen2.DashStyle = Drawing2D.DashStyle.Solid
        grayPen1.DashStyle = Drawing2D.DashStyle.DashDotDot

        'timer
        tmrClock.Enabled = True
        tmrClock.Interval = 50
        tmrClock.Start()


    End Sub

    Private Sub frmscr_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Windows.Forms.Cursor.Show()
    End Sub

    Private Sub frmscr_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        Me.Close()
    End Sub

    Private Sub frmscr_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        Me.Close()
    End Sub

    Private Sub frmscr_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
        Me.Close()
    End Sub

    Private Sub frmscr_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDoubleClick
        Me.Close()
    End Sub

    Private Sub frmscr_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        Static OldX As Integer
        Static OldY As Integer
        'Determines whether the mouse was moved and whetherthe movement was large.
        ''If so, the screen saver is ended.
        If (OldX > 0 And OldY > 0) And (Math.Abs(e.X - OldX) > 3 Or Math.Abs(e.Y - OldY) > 3) Then
            Me.Close()
        End If
        ''Assigns the current X and Y locations to OldX and OldY.
        OldX = e.X
        OldY = e.Y
    End Sub
    Private Sub DrawGrids(ByVal e As PaintEventArgs)

        ' Define Vertical grid points : track width in % : default values
        t1W = 15

        'track width in pixels
        t1Wp = t1W * scrW / 100

        'track x offset in pixels
        xo1p = 0


        ' Create points that define line.
        'vertical grid
        Dim ii As Integer

        For ii = 1 To 4 Step 1
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii
        For ii = 6 To 9 Step 1
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii

        For ii = 0 To 10 Step 5
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(Pens.Blue, point1, point2)
        Next ii


        'horizontal grid
        nhThk = scrH / 75


        For ii = 1 To nhThk Step 1
            Dim point1 As New Point(0, 75 * ii)
            Dim point2 As New Point(t1Wp, 75 * ii)

            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii

    End Sub


    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        e.Graphics.SmoothingMode = SmoothingMode.HighQuality

        'routine to draw the grid
        DrawGrids(e)

        'routine to draw the curve
        DrawCurve(e)

    End Sub

    Private Sub DrawCurve(ByVal e As PaintEventArgs)

        e.Graphics.DrawLine(greenPen2, xGR1, yGR1, xGR2, yGR2)

        'stores 
        xGR1 = xGR2
        yGR1 = yGR2

        'clear screen after line reaches screen bottom
        If i >= (scrH / 3.75) - 1 Then
            i = 1

            ClearForm(e)

            yGR1 = 0

        End If
    End Sub

    Private Sub ClearForm(ByVal e As PaintEventArgs)
        'To clear the screen before continuing drawing
        e.Graphics.Clear(Color.Black)
    End Sub

    Private Sub tmrClock_Tick(ByVal sender As System.Object,
     ByVal e As System.EventArgs) Handles tmrClock.Tick

        'increment variable i to compute screen location of next point
        i = i + 1

        'computes screen location (x,y) of next point 
        xGR2 = xo1p + t1Wp * (GR(i) - GRmin) / (GRmax - GRmin)
        yGR2 = (DEPT(i) - DepthFirst) * 25

        Refresh()
    End Sub

End Class

Graeme_Grant

Мы здесь не для того, чтобы писать ваш код для вас. Как мы можем помочь вам, если вы не покажете нам, что вы пробовали...

Richard MacCutchan

Убедитесь, что вы рисуете все линии в рамках одной и той же итерации процедуры рисования.

Ralf Meier

Я видел ваш код.
Мой вопрос : где определены все ваши переменные?
Пробовали ли вы работать без метода "ClearForm" в DrawCurve ?

Member 10118655

Все мои переменные определены как общедоступные в отдельном модуле.
Да, я пробовал его без метода "ClearForm".

Ralf Meier

Хорошо ... тогда предоставьте и эту кодовую часть ...
Тогда я мог бы смоделировать то, что происходит ...

Member 10118655

Модуль PubVar ' объявляет переменные и константы
Общественные константные входной_файл = "E:\testdata\test.txt"
Public Const ILDmin = 0.1, ILDmax = 100, RHOBmin = 1.8, RHOBmax = 2.8, NPHImin = -0.06, NPHImax = 0.54, SPmin = 20, SPmax = 120
Public Const BSmin = 6, BSmax = 16, CALImin = 6, CALImax = 16, DTmin = 40, DTmax = 140, GRmin = 0, GRmax = 150
Общественный отдел(100000), BS(100000), CALI( 100000), DT(100000), GR (100000), ILD(100000), RHOB(100000), NPHI(100000), SP (100000) как двойной
Public DepthTopFile, DepthBotFile As Double
Public DepthFirst, DepthLast As Double
Общественные NumRec Как Долго
Public scrW, scrH As Integer ' ширина экрана и высота
Общественные t1W, t2W, t3W, т4w, t5W, t6W, компания, ТТЦ, как ширина колеи число в %
Public t1Wp, t2Wp, t3Wp, t4Wp, t5Wp, t6Wp, tdWp As Integer ' ширина трека в пикселях
Public xoDp, xo1p, xo2p, xo3p, xo4p, xo5p, xo6p As Integer ' track x-offset in pixels
Public nhThn,nhMed, nhThk As Integer ' no. горизонтальных толщиной &усилителя; тонкие линии
Общественные nDec как целое-нет десятилетий в удельное сопротивление шкале
Public xGR0, xGR1, xGR2, yGR0, yGR1, yGR2 As Single
Public i, j, iScr, numScr как целое число
Конечный Модуль

Ralf Meier

ОК... Я протестировал ваш код и посмотрел с помощью отладчика, какие результаты появляются.
В моем тесте расчет для XGr2 и YGr2 (выполняемый с каждым тиком таймера) всегда дает один и тот же результат - 0.0
Где вычисляются другие переменные, которые вы используете для обоих умножений-все они тоже равны 0.0 ...

Member 10118655

Мои данные выглядят так, где массив в 1-м столбце - это "глубина", а 2-й столбец - "GR". Значения XGR2, YGR2 вычисляются нормально. Я уже пробовал. Другой модуль считывает их из файла на диске 'test.txt-в массивы "DEPT" и "GR".
--------------------------------------------------------
2423.9220 85.9
2424.0744 83.9
2424.2268 77.8
2424.3792 73.6
2424.5316 74.2
2424.6840 75.9
2424.8364 75.7
2424.9888 75.1
2425.1412 77.2
2425.2936 80.8
2425.4460 84.0
2425.5984 87.4
2425.7508 90.0
2425.9032 89.9
2426.0556 87.5
2426.2080 86.1
2426.3604 86.4
2426.5128 86.9
2426.6652 86.9
2426.8176 86.0
2426.9700 84.6
2427.1224 84.4
2427.2748 86.5
2427.4272 88.7
2427.5796 89.8
.....
.....

Graeme_Grant

Решение 2 решение вашей проблемы.

2 Ответов

Рейтинг:
2

Graeme_Grant

Вот рабочий макет:

Imports System.Drawing.Text

Public Class Form1
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Refresh()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        DrawLines(e.Graphics)
    End Sub

    Dim r As Random = New Random()
    Dim pens As Pen() = New Pen(4) _
        {
            New Pen(Brushes.Blue),
            New Pen(Brushes.Red),
            New Pen(Brushes.Green),
            New Pen(Brushes.Cyan),
            New Pen(Brushes.Purple)
        }

    Private Sub DrawLines(ByVal gr As Graphics)

        gr.TextRenderingHint = TextRenderingHint.AntiAlias

        For i As Integer = 1 To 5
            gr.DrawLine(pens(r.Next(0, 4)), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200))
        Next

    End Sub

End Class

Я предполагаю, что есть проблема с вашим кодом.


Member 10118655

Спасибо, но это не то, что я хочу сделать. По сути, я рисую линию, состоящую из многочисленных сегментов, где каждый сегмент должен быть нарисован с помощью события тика таймера. Предыдущие сегменты должны остаться.

Graeme_Grant

Проверьте решение 2 - оно действительно решает вашу проблему.

Graeme_Grant

Тогда ваша проблема заключается в том, что вы не сохраняете снимок графического объекта и не добавляете к нему, а каждый раз рисуете новый графический объект. Вот почему вы не видите никакой истории рисования.

Рейтинг:
2

Graeme_Grant

"где каждый сегмент должен быть нарисован с помощью события timer tick" - проблема в том, что вы не сохраняете снимок графического объекта и не добавляете к нему, а каждый раз рисуете новый графический объект. Вот почему вы не видите никакой истории рисования. (копия ответа из комментариев к решению 1).

Вот модифицированная версия решения 1:

Imports System.Drawing.Imaging
Imports System.Drawing.Text

Public Class Form1



    Private myBitmap As Bitmap

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Refresh()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        DrawLines(e.Graphics)
    End Sub

    Dim r As Random = New Random()
    Dim pens As Pen() = New Pen(4) _
        {
            New Pen(Brushes.Blue),
            New Pen(Brushes.Red),
            New Pen(Brushes.Green),
            New Pen(Brushes.Cyan),
            New Pen(Brushes.Purple)
        }

    Private Sub DrawLines(ByVal gr As Graphics)

        Dim myG As Graphics

        If myBitmap Is Nothing Then
            myBitmap = New Bitmap(ClientRectangle.Width, ClientRectangle.Height, PixelFormat.Format24bppRgb)
            myG = Graphics.FromImage(myBitmap)
            myG.Clear(Color.Black)
        Else
            myG = Graphics.FromImage(myBitmap)
        End If

        myG.TextRenderingHint = TextRenderingHint.AntiAlias
        myG.DrawLine(pens(r.Next(0, 4)), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200))

        gr.DrawImage(myBitmap, 0, 0, myBitmap.Width, myBitmap.Height)

        myG.Dispose()

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        BackColor = Color.Black
    End Sub
End Class


Member 10118655

Спасибо. Я попробую вашу методологию решения в своем коде и дам вам знать результат.

Graeme_Grant

Добро пожаловать...

Graeme_Grant

- Как ты там?