How Do I Draw This?
How Do I Draw This?
How Do I Draw This?
How Do I Draw This?
How Do I Draw This?
How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This?
How Do I Draw This? How Do I Draw This?
How Do I Draw This?
Go Back  Xtreme Visual Basic Talk > > > How Do I Draw This?


Reply
 
Thread Tools Display Modes
  #1  
Old 12-12-2011, 04:59 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default How Do I Draw This?


Ok I don’t even know where to start asking this question... Probably easiest to explain what I am trying to do with pictures.

Picture 1 shows an application that I am currently writing that uses the LineShape and OvalShape out of the Visual Basic Power Packs. As I change the index in the part number combo box the A, B & C dimension change to suit the dimension in the text boxes.

Problem is the limited shapes are fine to draw a router template guide, but they are somewhat limited when it comes to drawing more complex shapes like the router bits that make the shapes in Picture 2

Is there a graphic class that would allow me to plot points and joint the dots like you get in kids colouring in books? Or something a little more adept to complex shapes like curves?

I just spotted something called the Pen Class that I might need to look more into, but not knowing the first thing about graphics, can someone please point me in the right direction.

Edit:
Spotted some advice passel gave in another thread to search vb.net gdi+ tutorial and it looks like the Pen Class might have potential, although I am going to have to revisit some math by the looks of things.
Attached Images
File Type: jpg Picture 1.jpg (100.5 KB, 31 views)
File Type: png Router_bit_profiles_en.png (17.6 KB, 23 views)

Last edited by CodeCruncher; 12-12-2011 at 05:53 AM.
Reply With Quote
  #2  
Old 12-12-2011, 05:54 AM
DrPunk's Avatar
DrPunkHow Do I Draw This? DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

Pens are used to draw lines (Draw methods, like DrawRectangle). Brushes are used to fill shapes (Fill methods like FillRectangle).

You might want to look at the DrawPolygon/FillPolygon methods of the Graphics object -> http://msdn.microsoft.com/en-us/libr...llpolygon.aspx
__________________
There are no computers in heaven!
Reply With Quote
  #3  
Old 12-12-2011, 01:50 PM
AtmaWeapon's Avatar
AtmaWeaponHow Do I Draw This? AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

The nice thing about OOP is you can name objects after real-world things to describe what they do. Unfortunately, sometimes the best name for the job can leave you with unrealistic expectations. This is one of those cases. If you think the analogy through really well, it makes sense, but you have to know a little bit about everything for it to make sense.

Here's the spoiler. Think about pens in real life. Pens don't draw things. Pens are used to deliver ink to a medium, but the entity that holds the pen is what does the drawing. .NET pens are like that; they have a width and a color for their "ink", but a pen cannot draw something on its own. The entity that uses pens and brushes to draw is the Graphics object. That object has methods like DrawRectangle() that accept pens and brushes.

You can get that Graphics object in several ways. Usually the best is to rely on the one you get automatically from the OnPaint event. About that: it trips up many people that what you draw doesn't stay on the screen forever. Windows expects you to keep track of what you want to draw so you can draw it again whenever it decides to refresh. So you're going to need to be able to recreate the shapes you want whenever.

Since you need curves in your shape FillPolygon() is out unless you want to go to the trouble of approximating curves with lots of extra points. FillShape() lets you use a GraphicsPath object, which is sort of like a polygon you build from other simple shapes. Creating a path is sort of like writing a program that describes how to draw the shape. Here's a small example that draws something like the "Round Nose" shape from your diagram.

Code:
Imports System.Drawing.Drawing2D

Public Class Form1

    ' Get the Round Nose shape when we need it.
    Public Function GetRoundNoseShape(ByVal shapeLocation As Point) As GraphicsPath
        ' This is a bunch of constants and variables that make it much easier to do the math
        Const ShapeWidth As Integer = 150
        Const ThirdWidth As Integer = ShapeWidth \ 3
        Const ShapeHeight As Integer = 40
        Const ThreeQuartersHeight As Integer = 3 * ShapeHeight \ 4
        Dim x As Integer = shapeLocation.X
        Dim y As Integer = shapeLocation.Y

        Dim roundNose As New GraphicsPath()

        ' Top: a line, half-circle, and another line.
        roundNose.AddLine(x, y, ThirdWidth, y)
        roundNose.AddArc(x + ThirdWidth, y - ThreeQuartersHeight \ 2, ThirdWidth, ThreeQuartersHeight, 180, -180)
        roundNose.AddLine(x + 2 * ThirdWidth, y, x + ShapeWidth, y)

        ' Right side: straight line
        roundNose.AddLine(x + ShapeWidth, y, x + ShapeWidth, y + ShapeHeight)

        ' Bottom: straight line
        roundNose.AddLine(x + ShapeWidth, y + ShapeHeight, x, y + ShapeHeight)

        ' Since the left edge is straight, just close the figure
        roundNose.CloseFigure()

        Return roundNose
    End Function

    ' This is called every time Windows wants to redraw the form. A Graphics object is given to
    ' you via the Graphics property of the PaintEventArgs parameter.
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        ' GraphicsPath implements IDispose, so it must be disposed when you're done with it.
        Using path As GraphicsPath = GetRoundNoseShape(New Point(25, 35))
            e.Graphics.FillPath(Brushes.Orange, path)
        End Using
    End Sub

End Class
Drawing stuff isn't exactly a small topic, but that's a whirlwind tour of using paths to create figures.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #4  
Old 12-12-2011, 08:12 PM
passel's Avatar
passelHow Do I Draw This? passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

Another question is do the router bits have to be drawn on the fly. Since most applications would have boxes or racks of a number of router bits to choose from, if you have a finite set of images you can use the DrawImage method to transfer the image to your drawing, rather than have code to draw the shape.
The possible approaches are quite extensive. Working through a few tutorials will help with the basics of drawing.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #5  
Old 12-12-2011, 09:27 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

I thought about that approach passel as would probably be easier, but the purpose of the app is to calculate the clearance difference between the guide and the cutter, so I really wanted to keep everything to scale. I could use the pic approach in a corner somewhere to show what I was trying to do in case my shape doesn’t look anything like

When I get home tonight I will try AtmaWeapons code to see if I can taylor that approach to the problem first.
Reply With Quote
  #6  
Old 12-13-2011, 05:59 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Unfortunately there isn’t enough code to get it running and learn that way, so I will need to learn how to get the basic Pen Class working first before I can work out how to use this customised graphics object. I’m just too tired to do any more tonight.

Found this on MSDN which seems to draw a diagonal line, but couldn’t get it to run AtmaWeapons function. Been a long day the answer is probably staring me in the face.

Code:
    ' This example creates a PictureBox control on the form and draws to it. 
    ' This example assumes that the Form_Load event handler method is connected to the Load event of the form.

    Private pictureBox1 As New PictureBox()

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Dock the PictureBox to the form and set its background to white.
        pictureBox1.Dock = DockStyle.Fill
        pictureBox1.BackColor = Color.White

        ' Connect the Paint event of the PictureBox to the event handler method.
        AddHandler pictureBox1.Paint, AddressOf Me.pictureBox1_Paint

        ' Add the PictureBox control to the Form.
        Me.Controls.Add(pictureBox1)

        GetRoundNoseShape(shapeLocation:=New Point(10, 10))

    End Sub 'Form1_Load

    Private Sub pictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)

        ' Create a local version of the graphics object for the PictureBox.
        Dim g As Graphics = e.Graphics

        ' Draw a string on the PictureBox.
        g.DrawString("Diagonal line drawn on the control", New Font("Arial", 10), Brushes.Blue, New PointF(30.0F, 30.0F))

        ' Draw a line in the PictureBox.
        g.DrawLine(System.Drawing.Pens.Blue, pictureBox1.Left, pictureBox1.Top, pictureBox1.Right, pictureBox1.Bottom)


    End Sub 'pictureBox1_Paint
Reply With Quote
  #7  
Old 12-13-2011, 09:20 AM
AtmaWeapon's Avatar
AtmaWeaponHow Do I Draw This? AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Well, I'll try to explain it again.

The thing that draws is the Graphics object. If you look down the list of methods, you'll see big groups of DrawXXXX() and FillXXXX() methods. The DrawXXXX() methods use Pens and draw outlines. The FillXXXX() methods use brushes and fill shapes.

There's nothing to "getting the Pen class working". A Pen doesn't do anything. Its purpose is to describe what a line should look like when drawn. But it doesn't draw lines. It has a counterpart, Brush, that describes how to fill in shapes. Just like Pens, Brushes don't draw anything on their own. The extent of what you can do with a Pen or a Brush is create it, set properties, and pass it to the DrawXXXX() or FillXXXX() method you would like to use.

Why don't Pens and Brushes do the drawing? Several reasons, but the short story is in OOP designers strive to make each class responsible for as few logically different operations as possible (ideally you shoot for 1 logical operation per class.) Drawing a shape and representing the information about how to draw it are two completely different concepts. In API, it sort of works as if the Graphics object had properties for pens and brushes. It can get really messy to draw multiple shapes with different pens and brushes in that API.

Now let's talk practical code. Let's say you want to draw a red outlined circle, a thicker blue outlined square, and a green filled ellipse. The first thing you need is not a Pen or a Brush, but a Graphics object. In the example you are using in #6, you get this Graphics object from the PaintEventArgs passed to the picture box's Paint event handler. (In my example, overriding OnPaint() is a different technique for handling the form's Paint event.) It's not *vital* for you to store it in a variable like they did, but it is easier to type "g" than "e.Graphics" when you need it so most of the time you'll see that as the first line of a Paint handler. Here's the simplest way to write that code:
Code:
Private Sub pictureBox1_Paint(...)
    Dim g As Graphics = e.Graphics

    ' Draw a thin green triangle using one of the stock pens.
    g.DrawEllipse(Pens.Green, 0, 0, 32, 32)

    ' Draw a thicker blue rectangle.
    Dim bluePen As New Pen(Color.Blue, 3)
    g.DrawRectangle(bluePen, 40, 40, 32, 32)
    bluePen.Dispose()

    ' Fill a green rectangle
    Dim greenBrush As New SolidBrush(Color.Green)
    g.FillRectangle(greenBrush, 100, 100, 64, 64)
    greenBrush.Dispose()
End Sub
In the first case, one of the "stock" pens from the Pens class is used. These pens are automatically created by Windows when the system boots. Each has a thickness of 1 and uses the color in its name. If you just need a 1-pixel outline you should reach for one of these. Note how DrawEllipse() takes a Pen to describe how to draw the outline and the rest is information about where to draw the outline.

Next, the blue rectangle. A blue pen is created by passing the color blue, and it gets a thickness of 3 pixels. There are no built-in pens with a thickness greater than 1. That pen is used to draw a rectangle. The next line is important. The Pen class implements the IDisposable interface. This means it holds on to some resources that are expensive in some way. Objects that implement this interface expect you to call their Dispose() method as soon as you are finished with them. In this case, Pens hold on to GDI handles that are limited by the system; if you forget to call Dispose() you can get in a situation where your drawing breaks because you run out of pens. Always take care when dealing with objects that implement IDisposable.

Finally, a brush is used to fill a rectangle. Brushes work like pens: create, set properties, use, dispose.

That's not all you can do with Pens and Brushes; the classes have properties that let you change other aspects of how shapes are drawn. For example, the Pen.DashPattern property lets you define pens that draw dotted lines. You can read about those properties in the documentation.

Methods like Graphics.DrawPolygon() and Graphics.DrawPath() are more complicated, but only because the shapes they draw require more information.

So let's talk about why your attempt failed. The best way to do so is to describe what you wanted the code to do, then describe what it does. Let's focus on the Paint event handler, since that's what does the drawing.

What you wanted:
Code:
* Get the path for the Round Nose shape.
* Draw the path.
What it does:
Code:
* Draw a string.
* Draw a line.
While you call GetRoundNoseShape() in the Load event handler, you don't do anything with that shape. Take a look at post #3 again. Here's what my OnPaint() method did:
Code:
* Get the path for the Round Nose shape.
* Fill the path using a stock brush.
* Dispose of the path. (automatically happens due to the Using statement.)
See if you can figure out what's missing.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #8  
Old 12-13-2011, 04:55 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Thanks AtmaWeapon I have just been too tired to join the dots lately… you probably provided enough information if my mind was sharp and focused, but at the moment I kind of need to step through functioning code one line at a time to see what is taking place.

I generally find if I can F8 through the code, if there is something I don’t understand hovering over the line of code, or clicking on the little pluses often exposes the functionality / properties associated with it, and more often than not that helps me greatly understand the function of the code.

For the want of a better analogy… I know you don’t like to catch the fish for people, but you are happy to bait the hook, ordinarily it should be fairly obvious to most people to put the line in the water and wait, but often this is the hardest step for me to understand.

Whereas I find if I already have the fish on the hook on the river bank, my potential for learning is much greater because I can then see and work out how to take the fish off the hook, seeing how the fish was hooked without the confusion of catching it, allows me to better catch the next fish.

I don’t know if others have this back to front way of learning, but I like to start at the end and reverse back to the start to peel the layers off the process. I find if I start at the beginning and try to work forward I often go off on the wrong tangent and fumble around in the dark until I manage to stumble over the right path again, by which time serious doubts have crept in that I did it right.

Hopefully that makes sense… I did manage to work out from post 3 that the function you wrote was much like filling up the gas (petrol) tank on a car, it was full ready to go but the engine wasn’t started, problem was I couldn’t find the door to get in, that’s what I meant by learning to use the Pen class, I need to work out how to draw a simple shape before implementing the more sophisticated function you wrote.

I could sort of see how the diagonal line code worked, but I couldn’t make a logical connection to your function. Anyway I will try again tonight with the additional information you supplied but apologies if it isn’t obvious to me.
Reply With Quote
  #9  
Old 12-14-2011, 02:40 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

I copied the code from post 3 again into a new project and it worked today. Only thing I can think of is that I must have missed copying the OnPaint section, the three hour sleep I had this afternoon obviously helped.

#7 was easy to follow, thanks for that. I can see how everything else in the code works but these couple of things.

When I F8 it loads the form and triggers the OnPaint Sub, I suspect that when the form is drawn to screen it automatically calls the form paint or draw event to cause the OnPaint Sub to trigger?

Also never used either Protected or Overrides can you please explain what they do in simple terms.

Code:
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Hovering over “e” I see
e{ClipRectangle = {X = 0, Y = 0, Width = 284, Height = 262}}
Which appears to be the form size. Passing the rectangle parameters to the MyBase.OnPaint below I guess we are specifying the size of the canvas to paint on?
Code:
        MyBase.OnPaint(e)
If I have those couple of things right, the whole process seems quite straight forward.
Reply With Quote
  #10  
Old 12-14-2011, 04:16 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Find this kind of interesting...

Using path As GraphicsPath = ...

Which then passes Point values to the GetRoundNoseShape Function

Within the GetRoundNoseShape Function, roundNose is created

Dim roundNose As New GraphicsPath()

Several attributes are then stored in roundNose, and at the end roundNose is passed back to the GraphicPath called path

Return roundNose

I was wondering at first why a New GraphicsPath (roundNose) would be created in the GetRoundNoseShape Function, when there was already a GraphicsPath created in OnPoint Sub called path, then it dawned on me that only a GraphicsPath method can be put in the GraphicsPath called path.

Strange how I have never noticed this very obvious relationship between a Sub and a Function before...
Reply With Quote
  #11  
Old 12-14-2011, 12:54 PM
passel's Avatar
passelHow Do I Draw This? passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

I thought I should at least note that you can scale drawn images so if you created the image in some known size, you can scale it up or down when drawn to match the scale of your drawing, but of course it is still good to learn all the drawing tools you can, so drawing complex shapes as a series of "primatives" is good skill development.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #12  
Old 12-14-2011, 08:09 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

As a test last night I plotted the shaft and a bearing on the bottom of the shaft (basically an upside cross – 12 different location points)

Found something interesting by accident... The upside cross partially drew over the top of the round nose that AtmaWeapon coded, so it would appear whatever is drawn first will be overwritten / replaced by whatever you put on top, which should come in handy.

passel is that to use the larger size to get detail, and then scale back to fit???

So far I have been using the size values stored in an access database to maintain proportion, but I multiply every value by 5 to get it close to the size I want i.e. if the shaft diameter was 10mm, I would do 10 * 5 to get a size that was roughly 10mm on screen.

Is there some way to work out 10mm on screen, or because different screens have different resolutions it can’t be done programmatically?
Reply With Quote
  #13  
Old 12-14-2011, 09:50 PM
passel's Avatar
passelHow Do I Draw This? passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

To have a farily accurate "actual size" display on various monitors, you would have to have your program provide a calibration feature that a user could use with some measuring device, like a ruler. A recent thread, from the legacy VB side of the forum, but using GDI+ discussed the issue a bit, so if you're interested in more detail, you could read through that.

As for the use of pre-drawn images, it isn't for more detail, but rather if a shape was complicated enough that it would be easier to use existing "art", and just draw the image larger or smaller by using a scaletransform is a possibility.
I don't have the time to put together a specific example now, but I do have an old example that has scaling built into it as a demonstration. The code was originally written in C# for a co-worker who asked if C# code do the same type of graphic stuff I was doing in VB6. I later ported the code from C# to VB.Net as most on this forum are not interested in looking at C# code to help with their VB.Net questions.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #14  
Old 12-14-2011, 10:42 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Had a quick look at the demo and yes I see where you are going with that concept... You may have just given me a way to do some dials as well. I keep hearing that you can get dials for VB free on the web, but I have had absolutely no luck in ever finding them.

I did get a trial of ChartFx dials which was very good, but really hard to justify spending that kind of money when there is no commercial return, and may never get used.

But if I was to create my own dial in paint and use it as a back ground like you did, and then have the needle move like you did, I would be on my way. It would be nice to have some of those fancy faced dials but beggars can’t be choosers.

Edit:

Been having a play with passel's demo... made myself a nice new blue needle

Wow that is so easy when you can see it working. The dial pointer just rotates and drawn based on the (0,0) centre index. Pic attached.
Attached Images
File Type: jpg Blue Needle.jpg (27.2 KB, 7 views)

Last edited by CodeCruncher; 12-15-2011 at 02:43 AM.
Reply With Quote
  #15  
Old 12-15-2011, 05:19 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Quick question... tried using

MyBase.OnPaint(e)

But had to use

gbVis.Controls.Add(picBox)
picBox.Dock = DockStyle.Fill
AddHandler picBox.Paint, AddressOf Me.picBox_Paint

Because I wanted to have the image appear in the GroupBox not the main form. I couldn’t see a way to substitute (gbVis) for (e)

Is there a way to do it or did I have to use the AddHandler like I did?

Edit:
Worked out I can despense with the picturebox altogether and just add the handler to the group box.

AddHandler gbVis.Paint, AddressOf Me.picBox_Paint

Last edited by CodeCruncher; 12-15-2011 at 05:39 AM.
Reply With Quote
  #16  
Old 12-18-2011, 01:05 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Another quick question... Not all that important as the solution below works, but always nice to know if there is a tidier way of doing the centre circle with the system color "Control"

Code:
    Private Sub TopView_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)

        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias      'Makes circles smooth 
        Dim WC As Decimal = gbTopView.Width / 2                 'GroupBox Width Centre
        Dim HC As Decimal = gbTopView.Height / 2                'Groupbox Height Centre

        e.Graphics.FillEllipse(Brushes.PaleGreen, WC - 140, HC - 140, 280, 280) 'Draw and fill the largest circle.

        Dim MyPen As New Pen(SystemColors.Control, 25)          'Very thick line instead of filling centre hole
        e.Graphics.DrawEllipse(MyPen, WC - 12, HC - 12, 24, 24) 'Can you FillEllipse to do the same thing? Brushes has no SystemColors.Control to match Groupbox color
        MyPen.Dispose()

        Dim MyPen1 As New Pen(Brushes.Lime, DimW)
        e.Graphics.DrawEllipse(MyPen1, WC - DimB, HC - DimB, DimB * 2, DimB * 2)    'Template Guide wall
        MyPen1.Dispose()
        DimW = DimW / 2

        GuideTopViewA.Location = New Point(WC - 6, HC - 12)                                     'Position letter A just above centre
        e.Graphics.DrawLine(Pens.Black, WC - (DimA + DimW), HC - 1, WC - (DimA + DimW), HC - 9) 'Left side small vertical line
        e.Graphics.DrawLine(Pens.Red, WC - (DimA + DimW), HC - 5, WC + (DimA + DimW), HC - 5)   'Main horizontal line
        e.Graphics.DrawLine(Pens.Black, WC + (DimA + DimW), HC - 1, WC + (DimA + DimW), HC - 9) 'Right side small vertical line

        GuideTopViewB.Location = New Point(WC - 6, HC)                                          'Position letter B just below centre
        e.Graphics.DrawLine(Pens.Black, WC - (DimB + DimW), HC + 1, WC - (DimB + DimW), HC + 9) 'Left side small vertical line
        e.Graphics.DrawLine(Pens.Red, WC - (DimB + DimW), HC + 5, WC + (DimB + DimW), HC + 5)   'Main horizontal line
        e.Graphics.DrawLine(Pens.Black, WC + (DimB + DimW), HC + 1, WC + (DimB + DimW), HC + 9) 'Right side small vertical line

    End Sub
Attached Images
File Type: jpg Guide Pic.jpg (125.1 KB, 7 views)
Reply With Quote
  #17  
Old 12-18-2011, 09:51 AM
AtmaWeapon's Avatar
AtmaWeaponHow Do I Draw This? AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

System colors aren't constant like normal colors, so they get stashed away in a different place. .NET could make it *look* like they were constant at the cost of risking some temporal confusion as settings change. In the end it's best to ask for the system color then make a brush based on it. Generally you shouldn't even cache the result past one execution of a method since the point of using a system color is to have it change if the user changes settings.

System colors are defined in the KnownColor enumeration. I can't recall any methods that actually use these values; everything expects Color enumeration values. So you have to use Color.FromKnownColor to convert. From there, everthing is familiar:
Code:
Dim systemControlColor As KnownColor = KnownColor.Control
Dim drawColor As Color = Color.FromKnownColor(systemControlColor)
Dim b As New SolidBrush(drawColor)
e.Graphics.FillEllipse(b, ...)
b.Dispose()
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #18  
Old 12-19-2011, 01:17 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Thanks AtmaWeapon works a treat!
Reply With Quote
  #19  
Old 01-03-2012, 05:49 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

As you can see from the attached pics I am slowly coming to grips with the class. However I am missing some math equation but not sure what it is...

First to explain a few of the variables I have used.

StartPoint is just some random (at this time) fixed point (Decimal) at the bottom of the drawing to build up from.

SideView_Width_MidPoint is fairly self explanatory... it’s the SideView Groupbox Width Mid Point, or half of Groupbox width...

halfBitDimE is half of the Router Bit width.

ReturnMe3 is an accumulation of the first 3 segments you see below the radius which are subtracted from the StartPoint making a smaller number and therefore moving the drawing point up the screen.

Main.MetBitRadius.Text contains a value of 4.76mm (3/16) at runtime which is then multiplied by 5, like I have for the other vertical and horizontal lines. (Vertical are generally * 2.5 for either side of centre, making * 5)

Code:
        Dim gpTemp3 As New GraphicsPath()
        Dim r As Decimal = Main.MetBitRadius.Text * 5
        Dim XMe As Decimal = SideView_Width_MidPoint - halfBitDimE - r
        Dim YMe As Decimal = StartPoint - ReturnMe3 – (r / 2)
        Dim RecMe As New RectangleF With {.X = XMe, .Y = YMe, .Width = r, .Height = r}
        e.Graphics.DrawArc(Pens.Black, RecMe, -90, 90)
        gpTemp3.Dispose()
As you can see in the first bit of code I halved one of the radiuses, and in the second bit of code I have multiplied 3 out of the 4 radiuses * 2, which gives me an arc that is about 6-7mm. The first one is too small and the second code too large.

Code:
        Dim gpTemp3 As New GraphicsPath()
        Dim r As Decimal = Main.MetBitRadius.Text * 5
        Dim XMe As Decimal = SideView_Width_MidPoint - halfBitDimE - r * 2
        Dim YMe As Decimal = StartPoint - ReturnMe3 - r 'not * 2???
        Dim RecMe As New RectangleF With {.X = XMe, .Y = YMe, .Width = r * 2, .Height = r * 2}
        e.Graphics.DrawArc(Pens.Black, RecMe, -90, 90)
        gpTemp3.Dispose()
So he is my theory...
1) the * 5 I have used for the vertical and horizontal lines is not the right multiplier for the radius
2) I need to somehow get Pi or at least a quarter of it in there somewhere.

Also a bit stumped as to why I need to halve the Y (veritical) r value.

Let’s say I finished at the last point of 100, 100 and I want to draw an arc of 10,10 to the left of the finish point, I should subtract 10 from the horizontal 100 and 10 from the vertical 100 to give me a Top Left starting point.

But as you can see from the above code I need to subtract 10 from the horizontal, but only 5 from the vertical to get the arc in the right position.
Attached Images
File Type: jpg Radius3.jpg (16.4 KB, 5 views)
File Type: jpg Radius2.jpg (20.7 KB, 5 views)
Reply With Quote
  #20  
Old 01-03-2012, 06:52 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Figures the moment I put my head on the pillow an idea would come to me...

Putting a bit of a theory to the test I drew a second rectangle around the area I figured the arc should be drawn in....

Code:
        Dim gpTemp3 As New GraphicsPath()
        Dim r As Decimal = Main.MetBitRadius.Text * 5
        Dim XMe As Decimal = SideView_Width_MidPoint - halfBitDimE - r
        Dim YMe As Decimal = StartPoint - ReturnMe3 - r
        Dim RecMe As New RectangleF With {.X = XMe, .Y = YMe, .Width = r, .Height = r}
        e.Graphics.DrawArc(Pens.Black, RecMe, -90, 90)

        Dim RecMe2 As Rectangle
        RecMe2 = New Rectangle(XMe, YMe, r, r)
        e.Graphics.DrawRectangle(Pens.Blue, RecMe2)
        gpTemp3.Dispose()
Code:
        Dim gpTemp3 As New GraphicsPath()
        Dim r As Decimal = Main.MetBitRadius.Text * 5 * 2 'Increased arc size here...
        Dim XMe As Decimal = SideView_Width_MidPoint - halfBitDimE - r
        Dim YMe As Decimal = StartPoint - ReturnMe3 - r
        Dim RecMe As New RectangleF With {.X = XMe, .Y = YMe, .Width = r, .Height = r}
        e.Graphics.DrawArc(Pens.Black, RecMe, -90, 90)

        Dim RecMe2 As Rectangle
        RecMe2 = New Rectangle(XMe, YMe, r, r)
        e.Graphics.DrawRectangle(Pens.Blue, RecMe2)
        gpTemp3.Dispose()
And the reason why I have to halve the Y radius to get it to meet the drawing corner becomes obvious...

I thought the arc would go from Top Left to Bottom Right, but it seems it only goes to the half way mark on both X and Y axis.

X doesn’t show up the same because it finishes not touching an edge.

So the question I should be asking is DrawArc the right method for what I am trying to do, and if it is how do I scale it to keep the same ratio as the other lines that are 5 times the value shown in the text box?
Attached Images
File Type: jpg Radius4.jpg (23.3 KB, 6 views)
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
How Do I Draw This?
How Do I Draw This?
How Do I Draw This? How Do I Draw This?
How Do I Draw This?
How Do I Draw This?
How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This? How Do I Draw This?
How Do I Draw This?
How Do I Draw This?
 
How Do I Draw This?
How Do I Draw This?
 
-->