|
-
Nov 18th, 2010, 04:13 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Math Problem :[
Hey guys 
I have a problem with math rather than vb.
My aim is to imitate the hand of a clock i.e. rotate a line from a fixed point.
I thought it was easy trigonometry but Im really really tired and I cant figure it out so after I searched google with no success I decided to ask along.
Here is what I managed yet:
Code:
Public Class Form1
Dim Pt1 As Point = New Point(100, 100)
Dim Pt2 As Point = New Point(100, 75)
Dim Pt3 As Point = New Point(125, 100)
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
e.Graphics.FillEllipse(Brushes.White, 75, 75, 50, 50)
e.Graphics.DrawEllipse(Pens.Black, 75, 75, 50, 50)
e.Graphics.DrawLine(Pens.Black, Pt1, Pt2)
'Variable triangle
e.Graphics.DrawLine(Pens.Black, Pt1, Vary(90))
End Sub
Private Function Vary(ByVal variable As Integer) As Point
Dim height As Integer = 0
Dim Rads As Integer = (variable / 180) * 3.146
height = 25 * Math.Sin(Rads)
Dim tmpPt As Point = New Point(100 - height, 100 + height)
Return tmpPt
End Function
End Class
PS: Its in a kinda mess cause its just whats coming in my mind at that instance. What I want is to change the angle from 0 to 360 (Cos) and get the coords of the line.
Thanks in advance,
Skate
-
Nov 18th, 2010, 05:33 PM
#2
Re: Math Problem :[
Hi Skatebone, here's a few things you need to fix:
1. Make Rads a Double rather an Integer, because otherwise it will only range from 0 to 7 which would be a bit odd for a clock!
2. To draw an angled line, you set the height to the Sin of the angle and the width to the Cos.
I've marked these points in your code below:
 Originally Posted by Skatebone
Code:
Public Class Form1
Dim Pt1 As Point = New Point(100, 100)
Dim Pt2 As Point = New Point(100, 75)
Dim Pt3 As Point = New Point(125, 100)
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
e.Graphics.FillEllipse(Brushes.White, 75, 75, 50, 50)
e.Graphics.DrawEllipse(Pens.Black, 75, 75, 50, 50)
e.Graphics.DrawLine(Pens.Black, Pt1, Pt2)
'Variable triangle
e.Graphics.DrawLine(Pens.Black, Pt1, Vary(90))
End Sub
Private Function Vary(ByVal variable As Integer) As Point
Dim width As Integer
Dim height As Integer = 0
Dim Rads As Double = (variable / 180) * 3.146
width = Cint(25 * Math.Cos(Rads)
height = Cint(25 * Math.Sin(Rads))
Dim tmpPt As Point = New Point(100 - width, 100 + height)
Return tmpPt
End Function
End Class
You should find it works with those changes. I think it's a good idea to work with Option Strict On, especially with Math(s), which is why I added the Cint in the code.
BB
-
Nov 19th, 2010, 12:38 AM
#3
Thread Starter
Hyperactive Member
Re: Math Problem :[
 Originally Posted by boops boops
Hi Skatebone, here's a few things you need to fix:
1. Make Rads a Double rather an Integer, because otherwise it will only range from 0 to 7 which would be a bit odd for a clock!
2. To draw an angled line, you set the height to the Sin of the angle and the width to the Cos.
I've marked these points in your code below:
You should find it works with those changes. I think it's a good idea to work with Option Strict On, especially with Math(s), which is why I added the Cint in the code.
BB
Thanks alot dude 
A very strange thing is happening though.
When I put 0 degrees, i get an angle of 270
When I put 90 degrees I get and angle of 180
Wehn I put 180 degrees I get an angle of 90
Therefore there is a shift of -90degrees
Now:
Sin(0)=0
Cos(0)=1
Hmm I cant see why this is happening
-
Nov 19th, 2010, 02:33 AM
#4
Re: Math Problem :[
Positive angles are incremented in the clockwise direction since the point (0;0) is in the top left corner by default.
And separate your logic angles with the graphics angles.
Take sin() and cos() from your logic angle and only then subtract 90 degrees and reverse the sign to reflect in in graphics.
Last edited by cicatrix; Nov 19th, 2010 at 02:48 AM.
-
Nov 19th, 2010, 04:22 AM
#5
Re: Math Problem :[
I'm not sure I understood Cicatrix's comment but I'm sure he's right. Anyway, it's because of 100 - width, which you should change to 100 + width to make it work the way you want.
Then you have to remember that all angles in DotNet are measured from the positive x-axis. That means 0 degrees is the 3 o'clock position. So if you want your clock hand to start from 12 o'clock, the starting value should be 270 degrees or -90 degrees.
BB
-
Nov 19th, 2010, 05:06 AM
#6
Fanatic Member
Re: Math Problem :[
Well I'm not sure if this is resolved yet, but I wrote this out for my own benefit because I wanted to see if I could do it. This is for the "seconds" hand. I call this sub on a timer every second.
Code:
Private curAngle As Integer = 270 'start at the top (measuring clockwise where 0 degrees is a horizontal line)
Private mGraph As Graphics = Me.CreateGraphics 'create some graphics.
Private initialPoint As New Point(128, 113) 'this was the start point i chose within my form. The values matter little.
Private Sub DoGraphics()
mGraph.Clear(Me.BackColor) 'clear previous graphics
mGraph.DrawEllipse(Pens.Black, New Rectangle(initialPoint.X - 50, initialPoint.Y - 50, 100, 100)) 'draw the clock face.
curAngle += 6 'increase the "degrees" angle by 6
Dim inRads As Double = (curAngle * Math.PI) / 180 'convert to radians
Dim NewX As Integer = CInt(50 * Math.Cos(inRads)) 'calculate new X2 position
Dim NewY As Integer = CInt(50 * Math.Sin(inRads)) 'calculate new Y2 position
mGraph.DrawLine(Pens.Black, initialPoint.X, initialPoint.Y, initialPoint.X + NewX, initialPoint.Y + NewY) 'draw the line!
End Sub
If I helped you out, please take the time to rate me 
-
Nov 19th, 2010, 06:34 AM
#7
Re: Math Problem :[
 Originally Posted by Skatebone
I have a problem with math rather than vb.
And as such, it would be better suited for the Math Forum. 
Moved.
-
Nov 19th, 2010, 07:20 AM
#8
Re: Math Problem :[
Pity it was moved because the problem is not with math.
What seems to be missing is the ability to apply 2d transformations for GDI+
You can prepare a logic co-ordinate space to your liking.
See this example.
In the Form_Paint we create a transformation matrix and apply certain transformations to it:
1. We move the (0,0) coordinate to the center of the form
2. We scale down the form so that we have logical coordinates instead of physical pixels
3. We rotate the matrix -90 degrees so that zero was at 12 o'clock.
4. We draw the hands using ordinary maths without pain.
vb Code:
Imports System.Math
Imports System.Drawing.Drawing2D
Public Class frmClock
Private cp As PointF ' Center point
'Private rct As RectangleF ' Bounding rect
Private tmr As Timer
Private smallerside As Integer ' Whatever is smaller - width or height of the form
Private pixelwidth As Single ' Used to determine the scalefactor for a pixel
Private hrspen, minpen, secpen, dialpen As Pen ' individual pens for the hands
' A hour hand makes 1 full turn per 12 hours or 12 * 3600 = 43200 seconds
Private Const H_INCREMENT As Double = 2 * PI / 43200
' A minute hand makes 1 full turn per 3600 seconds
Private Const M_INCREMENT As Double = 2 * PI / 3600
' A second hand makes 1 full turn per 60 seconds
Private Const S_INCREMENT As Double = 2 * PI / 60
Private Const H_LENGTH As Double = 0.5 ' Length of the hours hand
Private Const M_LENGTH As Double = 0.7 ' Length of the minutes hand
Private Const S_LENGTH As Double = 0.79 ' Length of the seconds hand
Private Sub frmClock_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Creating a timer
tmr = New Timer With {.Interval = 1000, .Enabled = True}
' Lambda for the handling of Timer.Tick
AddHandler tmr.Tick, Sub(timersender As Object, timere As EventArgs)
Me.Invalidate()
End Sub
End Sub
Private Sub frmClock_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
' Find the central point
cp = New PointF(CSng(Me.ClientSize.Width / 2), CSng(Me.ClientSize.Height / 2))
' Determine whatever is smaller - width or height
smallerside = CInt(IIf(Me.ClientSize.Width >= Me.ClientSize.Height, Me.ClientSize.Height, Me.ClientSize.Width))
' Find out what will be a pixel size in our logic coordinates:
pixelwidth = CSng(1 / smallerside)
' Preparing pens for each hand and the dial:
hrspen = New Pen(Brushes.Blue, 8 * pixelwidth)
minpen = New Pen(Brushes.Green, 4 * pixelwidth)
secpen = New Pen(Brushes.Red, 1 * pixelwidth)
dialpen = New Pen(Brushes.Black, 4 * pixelwidth)
' Re-drawing the form
Me.Invalidate()
End Sub
Private Sub frmClock_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Me.Text = Now.ToString
Dim h_angle, m_angle, s_angle As Double ' For angles of each hand
' The transformation matrix
Dim mtrx As New Matrix
' Moving (0,0) to the center of the form
mtrx.Translate(cp.X, cp.Y)
' Scaling up the form (zoom in)
mtrx.Scale(smallerside * 0.5F, smallerside * 0.5F)
' Rotating -90 degrees
mtrx.Rotate(-90)
' Applying transformation
' Now we have a coordinate space
' with the center at (0,0) and
' the dial diameter of 0.9 of the smaller dimension of the form.
' And the angles are incremented CLOCKWISE!
e.Graphics.Transform = mtrx
Dim h, m, s As Double
' For 10:30 the hours will be 10.5 so that the hand was between 10 and 11
s = Now.Second
m = Now.Minute + s / 60
' 24 hour format requires removing 12 hours:
h = CDbl(IIf(Now.Hour > 12, Now.Hour - 12, Now.Hour)) + m / 60
' Determine the angle of each hand.
h_angle = h * 3600 * H_INCREMENT
m_angle = m * 60 * M_INCREMENT
s_angle = s * S_INCREMENT
' Calculating the coordinates of each hand:
Dim hpt As PointF = New PointF(CSng(Cos(h_angle) * H_LENGTH), CSng(Sin(h_angle) * H_LENGTH))
Dim mpt As PointF = New PointF(CSng(Cos(m_angle) * M_LENGTH), CSng(Sin(m_angle) * M_LENGTH))
Dim spt As PointF = New PointF(CSng(Cos(s_angle) * S_LENGTH), CSng(Sin(s_angle) * S_LENGTH))
' Center of the dial:
Dim stpt As Point = New Point(0, 0)
' Drawing the dial:
e.Graphics.DrawEllipse(dialpen, -0.9, -0.9, 1.8, 1.8)
' Drawing the hands:
e.Graphics.DrawLine(hrspen, stpt, hpt)
e.Graphics.DrawLine(minpen, stpt, mpt)
e.Graphics.DrawLine(secpen, stpt, spt)
End Sub
End Class
-
Nov 19th, 2010, 10:05 AM
#9
Thread Starter
Hyperactive Member
Re: Math Problem :[
This is all the help I could ever get
Thanks all guys really helped
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|