What should a class for drawing graphics look like?

  • Thread starter Thread starter tommytwotrain
  • Start date Start date
T

tommytwotrain

Guest
You may have seen some of the discussion from these recent threads about graphics and how to use classes and etc.

https://social.msdn.microsoft.com/F...inuation-of-the-bouncing-ball?forum=vbgeneral


I am learning classes and I made this simple one just to try it and then see what I thought. I thought I would show you all and let you comment on it. I am sure there are better and more prefered ways of doing it. ie Make some more classes and bases that can inherit and on and on...

So how would you improve this example class?

Then part of my thinking is what do I (we) need in a class for graphics. I dont really know where it is headed or even what its purpose is.

So what do you think would be useful?

The example shows using the class to draw two windows of different size and etc. The class is what, a drawing surface. Hopefully its self explanatory otherwise ask. The details are many and not yet worked out. I am just looking overall for now.

No laughing at my class Monkey!


a201e38b2ebb9b34eb27cb9a854157fc._.png



Create a new form and add this code:

Option Strict On

Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
y coordinate axis increasing upward by using neg vb coords
with yfactor and translate (0,0) to lower left
Dim Yfactor As Single = -1

draw scene fit to window
thescale is fit to the graphics width
Dim theScale As Single = 100
window in form coordinates
Dim graphicsrect As Rectangle = New Rectangle(10, 10, Me.ClientSize.Width - 20, Me.ClientSize.Height - 20)
Dim graphicsrect As Rectangle = New Rectangle(10, 10, 300, 300)
window in scene scaled coordinates
Dim scalerect As Rectangle = New Rectangle(0, 0, CInt(theScale), CInt(theScale))

create the drawing window
Dim ds As DrawScene = New DrawScene(e.Graphics, theScale, Yfactor, graphicsrect, scalerect)

With ds
.DrawGrid(e.Graphics)

e.Graphics.DrawLine(New Pen(Color.SlateBlue, 3), 50, Yfactor * 40, 50, Yfactor * 90)

.DrawCone(e.Graphics, New PointF(30, 70), 20)
.DrawSphere(e.Graphics, 50, 40, 15)

draw fixed size overlay
theScale = 100
graphicsrect = New Rectangle(180, 20, 200, 200)
scalerect = New Rectangle(0, 0, CInt(theScale), CInt(theScale))
ds = New DrawScene(e.Graphics, theScale, Yfactor, graphicsrect, scalerect)
.DrawGrid(e.Graphics)
.DrawSphere(e.Graphics, 50, 50, 40)
End With
End Sub

Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
Me.Invalidate()
End Sub
End Class





Create a new class named DrawScene and add this code:

Option Strict On
Imports System.Drawing.Drawing2D

Public Class DrawScene
Public Scale As Single
Public Yfactor As Single
Public gr As Graphics
Public GraphicsRect As Rectangle
Public ScaleRect As Rectangle

Public Sub New(_gr As Graphics, ByVal _Scale As Single, _Yfactor As Single, _GraphicsRect As Rectangle, _ScaleRect As Rectangle)
Scale = _Scale
Yfactor = _Yfactor
gr = _gr
GraphicsRect = _GraphicsRect
ScaleRect = _ScaleRect

With gr
.ResetClip()
.ResetTransform()

move origin to lower left
.TranslateTransform(GraphicsRect.X, GraphicsRect.Y + GraphicsRect.Height)

set up the drawing coordinate window and scale to fit smallest graphicsrect size
Dim scaleratio As Single = GetScaleRatio(GraphicsRect)
.ScaleTransform(scaleratio, scaleratio)

Dim rect As Rectangle = New Rectangle(ScaleRect.X, CInt(-(Scale - ScaleRect.Y)), ScaleRect.Width, ScaleRect.Height)
.SetClip(rect)
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
.Clear(Color.Black)

End With
End Sub

Public Sub DrawGrid(g As Graphics)
Dim increment As Single
Select Case Scale
Case Is < 1.5 : increment = 0.2
Case Is < 3 : increment = 0.5
Case Is < 7 : increment = 1
Case Is < 15 : increment = 2
Case Is < 30 : increment = 5
Case Is < 70 : increment = 10
Case Is < 150 : increment = 20
Case Is < 300 : increment = 50
Case Is < 700 : increment = 100
Case Is < 1500 : increment = 200
Case Else : increment = 0
End Select

Dim textheight As Single = Scale / 10
Dim scaleratio As Single = GetScaleRatio(GraphicsRect)
textheight = 12 / scaleratio
textheight = Scale / (8 * GraphicsRect.Width / g.DpiX)

draw grid
Using f As New Font("Arial", textheight), _
p As Pen = New Pen(Color.SkyBlue, 0.01), _
br As New SolidBrush(Color.Gray)

For x As Single = 0 To Scale Step increment
x axis
g.DrawLine(p, x, 0, x, Yfactor * Scale)
g.DrawString(x.ToString, f, br, x, CSng(Yfactor * 1.5 * textheight))
y axis
g.DrawLine(p, 0, -x, Scale, Yfactor * x)
g.DrawString((x).ToString, f, br, 0, CSng(Yfactor * (1.5 * textheight + x)))
Next
End Using
End Sub

Public Sub DrawSphere(g As Graphics, x As Single, y As Single, r As Single)
x, y is the location of the sphere center
Dim rectf As RectangleF = New RectangleF(x - r, Yfactor * (y + r), 2 * r, 2 * r)
Dim path As New GraphicsPath()
path.AddEllipse(rectf)
rectf.X += r / 50
rectf.Y += r / 50
g.DrawEllipse(New Pen(Color.LightGray, r / 16), rectf)

Using pthGrBrush As New PathGradientBrush(path)
pthGrBrush.CenterPoint = New PointF(x + r, -10)
pthGrBrush.CenterColor = Color.Gray
Dim colors As Color() = {Color.WhiteSmoke}
pthGrBrush.SurroundColors = colors
g.FillPath(pthGrBrush, path)

pthGrBrush.CenterColor = Color.LightGray
rectf.Width *= 0.2F
rectf.Height *= 0.2F
rectf.Offset(r / 3, r / 2)
g.FillEllipse(pthGrBrush, rectf)
End Using
End Sub

Public Sub DrawCone(g As Graphics, ApexPt As PointF, ConeHeight As Single)
ApexPt is the location of the cone apex, ul = upperleft, lr = lower right etc.
bottom arc
Dim rectf As RectangleF = New RectangleF(ApexPt.X - ConeHeight, Yfactor * CSng((ApexPt.Y - (1.49 * ConeHeight))), 2 * ConeHeight, ConeHeight)
Dim path1 As New GraphicsPath()
path1.AddArc(rectf, 180, -180)

top triangle
Using lgbr As New LinearGradientBrush(rectf, Color.Gray, Color.WhiteSmoke, 190)
g.FillPath(lgbr, path1)
path1.Reset()

Dim ll As PointF
ll.X = ApexPt.X - ConeHeight
ll.Y = Yfactor * (ApexPt.Y + (-2 * ConeHeight))

Dim lr As PointF
lr.X = ApexPt.X + ConeHeight
lr.Y = Yfactor * (ApexPt.Y + (-2 * ConeHeight))

Dim t As PointF
t.X = ApexPt.X
t.Y = -ApexPt.Y

Dim thePolygon() As PointF = {ll, t, lr}
create a path from the coordinate polygon and fill with gradient color
path1.AddLines(thePolygon)
g.FillPath(lgbr, path1)
End Using
End Sub

Private Function GetScaleRatio(grect As Rectangle) As Single
If grect.Width >= grect.Height Then
GetScaleRatio = grect.Height / Scale
Else
GetScaleRatio = grect.Width / Scale
End If

End Function
End Class

Continue reading...
 

Similar threads

V
Replies
0
Views
150
Vergassivellaunus
V
V
Replies
0
Views
154
Vergassivellaunus
V
D
Replies
0
Views
190
David William Smith
D
Back
Top