Рисовать круги из массива в форму


Я на самом деле боролся с картиной с VB.Net в течение нескольких недель. Все, что я знаю, что я не должен использовать CreateGraphics Если я могу избежать его, поэтому я сделал это. Одним из вопросов приходит от CodeGolf вызов, который требует, чтобы пользователи рисуют звездочки.

Это только мое начало. Я никогда ничего я не рисовал в Excel. Сначала я попробовал класс звездочки, но это не правильно заполнить моем списке, поэтому я свела все к

  1. заполнение массива
  2. пройдя этот массив в форме
  3. Картина моих кругах.

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

Вход

Поставляется в виде (наборы) 3 целых чисел (х-позиция, позиция-y, радиус) например

(0, 0, 16),  (100, 0, 16),  (100, 100, 12),  (50, 50, 24),  (0, 100, 12)

Выход

enter image description here

Стандартный Модуль

Option Explicit On
Option Strict On
Option Infer On
Option Compare Text
Imports System.IO
Module Module1
    Const INPUT_PATH As String = "C:\Temp\gearinput.txt"
    Public delimiter() As String = {"),"}
    Sub Main()
        Dim inputData() As String
        inputData = GetInput()
        Dim sprocketData() As String = Custom_Split(inputData(0))
        Dim paintingdata(,) As Integer = StringToIntArray(sprocketData)
        Dim targetForm As New Form1
        targetForm.Visible = True
        targetForm.DrawSprockets(targetForm, paintingdata)
    End Sub
    Private Function Custom_Split(ByVal stringToSplit As String) As String()
        stringToSplit = stringToSplit.Replace("(", String.Empty)
        stringToSplit = stringToSplit.Replace(" ", String.Empty)
        Dim stringArray() As String = stringToSplit.Split(delimiter, StringSplitOptions.RemoveEmptyEntries)
        stringArray(stringArray.Length - 1) = stringArray(stringArray.Length - 1).Replace(")", String.Empty)
        Return stringArray
    End Function
    Private Function StringToIntArray(ByVal sprocketdata() As String) As Integer(,)
        Dim firstDimensionSize As Integer = sprocketdata.GetUpperBound(0)
        Dim integerArray(firstDimensionSize, 2) As Integer
        Dim tempString() As String
        For i As Integer = 0 To firstDimensionSize
            tempString = sprocketdata(i).Split(","c)
            For j = 0 To 2
                integerArray(i, j) = Convert.ToInt32(tempString(j))
            Next
        Next
        Return integerArray
    End Function

    Private Function GetInput() As String()
        Return File.ReadAllLines(INPUT_PATH)
    End Function
End Module

Форма Код

Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Const BUFFER As Integer = 20
 Dim xValue As Integer
    Dim yValue As Integer
    Dim pRadius As Integer
    Dim paintData(,) As Integer
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

    End Sub
Public Shared Sub DrawSprockets(ByVal myForm As Form1, ByVal dataArray(,) As Integer)
        myForm.paintData = dataArray
        For i As Integer = 0 To myForm.paintData.GetUpperBound(0)
            myForm.paintData(i, 0) += 10
            myForm.paintData(i, 1) += 10
        Next
        myForm.Refresh()
    End Sub


    Private Sub Form1_Paint(ByVal sender As Object, e As PaintEventArgs) Handles MyBase.Paint
Dim myPen As Pen

        myPen = New Pen(Brushes.Black)

        For i As Integer = 0 To paintData.GetUpperBound(0)
            e.Graphics.DrawEllipse(myPen, New Rectangle(paintData(i, 0), paintData(i, 1), paintData(i, 2), paintData(i, 2)))
            e.Graphics.FillEllipse(Brushes.Black, New Rectangle(paintData(i, 0), paintData(i, 1), paintData(i, 2), paintData(i, 2)))

        Next

    End Sub

End Class


147
6
задан 24 марта 2018 в 12:03 Источник Поделиться
Комментарии
1 ответ

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

А не используя массивы, создать специальную "звездочки" класса провести синтаксический анализ входных данных.

Public Class Sprocket
Public Property X As Integer
Public Property Y As Integer
Public Property R As Integer
End Class

Теперь, если вы добавить остальные нечисловые символы в качестве разделителя списка вы могли бы читать и парсить файл в две строчки. (Хотя вы ougth использовать символ продолжения строки для удобочитаемости, как видно внизу)

Dim numbers = File.ReadAllText("C:\Temp\gearinput.txt").Split($"{Environment.NewLine} ,)(".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(Function(n) Integer.Parse(n)).ToArray()
Dim sprockets = Enumerable.Range(0, (numbers.Length \ 3)).Select(Function(i) New Sprocket With {.X = numbers(((i * 3) + 0)), .Y = numbers(((i * 3) + 1)), .R = numbers(((i * 3) + 2))}).ToArray()


Window

Звездочку.глаг

Public Class Sprocket

Public Property X As Integer
Public Property Y As Integer
Public Property R As Integer

Public Overrides Function ToString() As String
Return $"{{ X={Me.X}, Y={Me.Y}, R={Me.R} }}"
End Function

End Class

Программы.глаг

Public Module Program

<STAThread>
Public Sub Main()

'TODO: Read file
Dim input = "(0, 0, 16), (100, 0, 16), (100, 100, 12), (50, 50, 24), (0, 100, 12)"

Dim numbers = input _
.Split($"{Environment.NewLine} ,)(".ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
.Select(Function(n) Integer.Parse(n)) _
.ToArray()

Dim sprockets = Enumerable _
.Range(0, (numbers.Length \ 3)) _
.Select(Function(i) New Sprocket With
{
.X = numbers(((i * 3) + 0)),
.Y = numbers(((i * 3) + 1)),
.R = numbers(((i * 3) + 2))
}) _
.ToArray()

Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Window(sprockets))

End Sub

End Module

Окна.глаг

Public Class Window
Inherits Form

Private ReadOnly sprockets As Sprocket()

Public Sub New(sprockets As Sprocket())

If (sprockets Is Nothing) Then
Throw New ArgumentNullException(NameOf(sprockets))
End If

Me.sprockets = sprockets

Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True)

Me.Text = "Sprockets"
Me.AutoScaleMode = AutoScaleMode.Font
Me.ClientSize = New Size(800, 450)

End Sub

Protected Overrides Sub OnPaint(e As PaintEventArgs)

e.Graphics.Clear(Me.BackColor)
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality

For Each sprocket In Me.sprockets

Dim diameter = (sprocket.R * 2)
Dim rect = New Rectangle(sprocket.X, sprocket.Y, diameter, diameter)

e.Graphics.FillEllipse(Brushes.Black, rect)

Next

End Sub

End Class

3
ответ дан 27 марта 2018 в 04:03 Источник Поделиться