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!
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...
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!
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...