Answered by:
incorrectly plotted point when angle is 90

Question
-
Answers
All replies
-
-
-
The trig functions expect the angle to be in radians ( (degrees / 180) * Math.PI )
Thanks. I'd already found that error, but that's unfortunately just part of it.
At the moment, I'm trying to completely rewrite it using a start point (any point is ok) and 1 preliminary line length and 3 angles. After drawing a triangle, i'm scaling and offsetting it to draw in a bitmap...
Any help with that would be appreciated...
thanks for any help
- Edited by .paul. _ Wednesday, July 8, 2015 9:35 AM
-
The trig functions expect the angle to be in radians ( (degrees / 180) * Math.PI )
Thanks. I'd already found that error, but that's unfortunately just part of it.
At the moment, I'm trying to completely rewrite it using a start point (any point is ok) and 1 preliminary line length and 3 angles. After drawing a triangle, i'm scaling and offsetting it to draw in a bitmap...
Any help with that would be appreciated...
thanks for any help
I cant duplicate it. Seems correct.
You say it is wrong when you plot it? How are you plotting it? Can you show the code?
-
PS in this example article I show how to rotate and scale a bitmap using math. If you want to put it in a triangle you can create a path of the triangle and use setclip to crop the bitmap with the path. You can also do this with a texture brush. If you show the result you want I am sure we can work it out.
'draw using manual coordinate calculations Dim cx As Double = Me.ClientSize.Width / 2 Dim cy As Double = Me.ClientSize.Height / 2 'center in form and scale Dim corners(2) As PointF corners(0) = New PointF(CSng(cx - (ScaleFactor * bm_rusty.Width / 2)), CSng(cy - (ScaleFactor * bm_rusty.Height / 2))) corners(1) = New PointF(CSng(cx + (ScaleFactor * bm_rusty.Width / 2)), CSng(cy - (ScaleFactor * bm_rusty.Height / 2))) corners(2) = New PointF(CSng(cx - (ScaleFactor * bm_rusty.Width / 2)), CSng(cy + (ScaleFactor * bm_rusty.Height / 2))) 'rotate Dim X As Double For i = 0 To 2 X = corners(i).X corners(i).X = CSng(corners(i).X * Math.Cos(Rotation) + corners(i).Y * Math.Sin(Rotation)) corners(i).Y = CSng((corners(i).Y * Math.Cos(Rotation)) - (X * Math.Sin(Rotation))) Next i 'translate back to center Dim newcx As Double = corners(2).X + (corners(1).X - corners(2).X) / 2 Dim newcy As Double = corners(2).Y + (corners(1).Y - corners(2).Y) / 2 For i = 0 To 2 corners(i).X = CSng(corners(i).X + (cx - newcx)) corners(i).Y = CSng(corners(i).Y + (cy - newcy)) Next i
e.Graphics.Clear(Color.White) e.Graphics.DrawImage(bm_rusty, corners
-
Here is an example with a path using setclip. There is a texturebrush that is commented out. I don't know if it works.
If you want to use math you have to combine things.
Imports System.Drawing.Drawing2D Public Class LabelRotateStarWinner 'label control with rotating star shape Private path1 As New Drawing2D.GraphicsPath Private bmpBackground1 As Bitmap = Image.FromFile("c:\bitmaps\mil.jpg") Private WithEvents timer1 As New Windows.Forms.Timer With {.Interval = 50} Private rotation As Single = 180 Private blink As Boolean = True Private Sub Form8_Load(sender As Object, e As EventArgs) Handles MyBase.Load With Label2 .AutoSize = False .Top = 10 .Left = 10 .Width = 300 .Height = 300 .Text = "Winner" .Font = New Font("Rockwell Extra Bold", 48) .ForeColor = Color.Firebrick .TextAlign = ContentAlignment.MiddleCenter '.Image = bmpBackground1 End With Me.Width = 1.2 * Label2.Width Me.Height = 1.2 * Label2.Height 'create the star shape polygon Dim thePolygon() As PointF = {New PointF(5, 9), New PointF(6, 6), New PointF(9, 6), New PointF(7, 4), New PointF(8, 1), New PointF(5, 3), New PointF(2, 1), New PointF(3, 4), New PointF(1, 6), New PointF(4, 6), New PointF(5, 9)} path1.AddLines(thePolygon) timer1.Start() End Sub Private Sub Label2_Paint(sender As Object, e As PaintEventArgs) Handles Label2.Paint Dim w = Label2.ClientSize.Width / 2 Dim h = Label2.ClientSize.Height / 2 With e.Graphics .ResetTransform() .Clear(Color.Black) .ScaleTransform(2 * w / 10, 2 * h / 10) '.TranslateTransform(5, 5) '.RotateTransform(rotation) ''.TranslateTransform(-5, -5) Dim mx As Matrix = .Transform mx.RotateAt(rotation, New PointF(w, h), MatrixOrder.Append) .Transform = mx 'draw polygon path using texture brush containing bitmap 'scale, rotate bitmap inside polygon and draw 'Using tb As New TextureBrush(bmpBackground1) ' tb.RotateTransform(180) ' tb.ScaleTransform(10 / bmpBackground1.Width, 10 / bmpBackground1.Height) ' .FillPath(tb, path1) 'End Using 'draw the image slice using the path clipping .SetClip(path1) .DrawPath(New Pen(Brushes.Goldenrod, 0.1), path1) .DrawImage(bmpBackground1, 1, 1, 7, 7) .ResetClip() .DrawPath(New Pen(Brushes.Goldenrod, 0.1), path1) .ResetTransform() If blink Then .DrawString(Label2.Text, Label2.Font, Brushes.White, 2, 2 + h / 3) .DrawString(Label2.Text, Label2.Font, New SolidBrush(Label2.ForeColor), 0, h / 3) End If End With End Sub Private Sub timer1_Tick(sender As Object, e As EventArgs) Handles timer1.Tick Static blinkcount As Integer blinkcount += 1 If blinkcount > 6 Then blink = Not blink blinkcount = 0 End If rotation += 4 If rotation > 360 Then rotation -= 360 Label2.Refresh() End Sub End Class
- Edited by tommytwotrain Wednesday, July 8, 2015 2:20 PM
-
At the moment, I'm trying to completely rewrite it using a start point (any point is ok) and 1 preliminary line length and 3 angles. After drawing a triangle, i'm scaling and offsetting it to draw in a bitmap...
Hi,
will this triangle be a shape you later want to somehow move/resize/render? If so, I'd generate a class for it and add a constuctor that takes a point, a length and the angles as parameters. (This way you could add other contructors easily). Also I'd put some Properties to it, like the "geometry" (eg a GraphicsPath), the Brush to draw it and a Zoom Property and so on.
Regards,
Thorsten
- Edited by Thorsten Gudera Wednesday, July 8, 2015 3:16 PM
-
It doesn't calc to 520 on my system for some reason. I suppose tommytwotrain's code is accurate since he does all this stuff in his head with no probs (unless there's a typo in the code which I doubt). It would take me a long time to figure out the math and I don't know what you're trying to do with this .paul. _. :)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim pt1 As New Point(CInt(500 - 6 * Math.Cos(90)), CInt(500 + 6 * Math.Sin(90))) Label1.Text = "pt1.X = " & pt1.X.ToString & vbCrLf & "pt1.Y = " & pt1.Y.ToString Dim ptf1 As New PointF(CSng(500 - 6 * Math.Cos(90)), CSng(500 + 6 * Math.Sin(90))) Label2.Text = "ptf1.X = " & ptf1.X.ToString & vbCrLf & "ptf1.Y = " & ptf1.Y.ToString Dim pt2 As New Point(CInt(500 - 6 * Math.Cos(Math.PI / 2)), CInt(500 + 6 * Math.Sin(Math.PI / 2))) Label3.Text = "pt2.X = " & pt2.X.ToString & vbCrLf & "pt2.Y = " & pt2.Y.ToString Dim ptf2 As New PointF(CSng(500 - 6 * Math.Cos(Math.PI / 2)), CSng(500 + 6 * Math.Sin(Math.PI / 2))) Label4.Text = "ptf2.X = " & ptf2.X.ToString & vbCrLf & "ptf2.Y = " & ptf2.Y.ToString End Sub
La vida loca
-
I had another try at the code, but it's still way off. I need the three points for drawing line and angle labelling (which is working), it's just finding the points that eludes me...
's_c is side AB 'a_A is angle A Dim ptA As New Point(500, 500) Dim x As Integer = CInt(500 - (s_c * 10) * Math.Cos((720 - a_A) * (Math.PI / 180))) Dim y As Integer = CInt(500 + (s_c * 10) * Math.Sin((720 - a_A) * (Math.PI / 180))) Dim ptB As New Point(x, y) 's_a is side BC 'a_B is angle B Dim newX As Integer = CInt(x - (s_a * 10) * Math.Cos((720 - a_A + a_B) * (Math.PI / 180))) Dim newY As Integer = CInt(y + (s_a * 10) * Math.Sin((720 - a_A + a_B) * (Math.PI / 180))) Dim ptC As New Point(newX, newY) Dim lineAB As Integer = lineLength(ptA, ptB) 'this is just a function that measures pixel length of the line Dim lineBC As Integer = lineLength(ptB, ptC) 'same here Dim pts() As Point = New Point() {ptA, ptB, ptC} Dim multiplier As Decimal = CDec(250 / Math.Max(pts.Max(Function(p) p.X) - pts.Min(Function(p) p.X), pts.Max(Function(p) p.Y) - pts.Min(Function(p) p.Y))) ptB = MaxDistanceEndPoint(ptA, ptB, CInt(lineAB * multiplier)) 'this is a function that will either extend or reduce the length between 2 points ptC = MaxDistanceEndPoint(ptB, ptC, CInt(lineBC * multiplier)) 'same here centreTriangle(ptA, ptB, ptC) 'this centres the triangle in a (300,300) area
thanks for any help
-
Hi .paul. _,
I notice in your Math functions you are using Math.Sin( 720 - a_A )
Ignoring the fact whether you use Sin or Cos for a minute.
You need to convert 720 degrees to radians and the
a_A
value to radians in order for the whole thing to work properly.
Put this just below the line Public Class Form1
like this.>>
Public Class Form 1 Private degreesToRadians As Double = Math.Pi /180 End Class
then you can use it in any calculation line like this.
>>Dim x As Integer = CInt(500 - (s_c * 10) * Math.Cos((720/degreesToRadians) - (a_A/degreesToRadians)))
I hope this helps.
Basically anywhere within any trigonometry MATH function such as Sin, Cos, Tan etc the values need to be in radians.
If you need to convert any angle back to DEGREES then multiply by the degreesToRadians value this would usually be done after using ASin, ACos, ATan on the angle specified in Radians.
If you are plotting on a PictureBox then stick to doing everything in Radians but you may want to show the values in Degrees in TextBoxes or Labels?
Regards,
Click this link to see the NEW way of how to insert a picture into a forum post.
Installing VB6 on Windows 7
App Hub for Windows Phone & XBOX 360 developers.
- Edited by John Anthony Oliver Thursday, July 9, 2015 3:53 PM