Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Go Back  Xtreme Visual Basic Talk > > > Problem drawing dotted path lines, with even dots along the path line


Reply
 
Thread Tools Display Modes
  #1  
Old 04-13-2012, 01:44 AM
coolpjmartin coolpjmartin is offline
Newcomer
 
Join Date: Mar 2010
Posts: 1
Default Problem drawing dotted path lines, with even dots along the path line


Problem drawing dotted path lines, with even dots along the path line.

I want to draw a path line that can be any shape (square, round, outline etc), and along this path line I want even dots to appear.

I also want to be able to resize the shape (as in the example attached)

This is very easy to do using “DrawPath” and defining points for the path and using a pen defined as dots.

The problem I have is I want the dots to be evenly placed along the path, on any shape or size I draw.

In the example I have created, I create a square with 4 points and draw a dotted path.

There are 2 buttons that allows me to resize the square (larger or smaller) this helps show the problem more clearly.

The path starts at the top left corner and finishes back at the top left corner, the dots are evenly placed along the path, except the final dots at the end of the path. (Sometimes the dots are even and other times they are not even).

The shapes I want to draw can be any size and any shape, but I have used a square in this example to show the problem I have.


Can anyone please help point me in the direction I need to go that allows me to draw the dots and give the impression that they are even all along the path, for all shapes and sizes.

In the pictures below if you change the size of the shape, one will have even looking dots, the other will not.

Good:
The picture shows a path line that has dots that look even.


Any help much appreciated

Setting up the project:

Create a new project and add a form, add a panel to the form that fills the bottom part of the form, add at the top of the form a label and 2 buttons.

Add the code below to the form:

Full project also available for download:

http://craftysams.co.uk/ItemImages/W...dottedline.zip




Code:
Imports System.Drawing.Drawing2D
Imports System.Math


Public Class Form1

    Public pathLinesStart As GraphicsPath = New GraphicsPath

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

        Dim TPoint(5) As PointF
        Dim Npoint As PointF = Nothing
        'For x1 As Integer = 0 To 4
        'Npoint = New PointF(30, 30)
        'TPoint(0) = Npoint
        'Npoint = New PointF(300, 30)
        'TPoint(1) = Npoint
        'Npoint = New PointF(300, 300)
        'TPoint(2) = Npoint
        'Npoint = New PointF(30, 300)
        'TPoint(3) = Npoint
        'Npoint = New PointF(30, 30)
        'TPoint(4) = Npoint
        'Npoint = New PointF(30, 30)
        'TPoint(5) = Npoint


        Npoint = New PointF(126, 126)
        TPoint(0) = Npoint
        Npoint = New PointF(205, 126)
        TPoint(1) = Npoint
        Npoint = New PointF(205, 205)
        TPoint(2) = Npoint
        Npoint = New PointF(126, 205)
        TPoint(3) = Npoint
        Npoint = New PointF(126, 126)
        TPoint(4) = Npoint
        Npoint = New PointF(126, 126)
        TPoint(5) = Npoint

        'Next
        pathLinesStart.AddLines(TPoint)

        CalculateNewPoints(True, 0)
        Me.Refresh()

    End Sub

    Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint

        Dim p As Pen = New Pen(Color.Black, 5)
        p.LineJoin = LineJoin.Round
        p.EndCap = LineCap.Round
        p.StartCap = LineCap.Round

        Dim g As Graphics = e.Graphics

        p.DashStyle = DashStyle.Dot
        p.DashCap = DashCap.Round

        g.InterpolationMode = InterpolationMode.HighQualityBicubic
        g.SmoothingMode = SmoothingMode.HighQuality
        p.Color = Color.Red
        g.DrawPath(p, pathLinesStart)

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ' Increase change point size
        CalculateNewPoints(True, 10)
        Me.Refresh()

    End Sub



    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        ' Decrease change point size
        CalculateNewPoints(False, 10)
        Me.Refresh()

    End Sub

    Public Sub CalculateNewPoints(ByRef Increase As Boolean, ByVal PercentageChange As Double)


        Dim RotatePerc As Single = 0

        Dim pathLines As GraphicsPath = pathLinesStart

        Dim xmin As Single = 0
        Dim xmax As Single = 0
        Dim ymin As Single = 0
        Dim ymax As Single = 0
        Dim xmin2 As Single = 0
        Dim xmax2 As Single = 0
        Dim ymin2 As Single = 0
        Dim ymax2 As Single = 0

        Dim CPoint As PointF = New Point(0, 0)
        Dim CPoint2 As PointF = New Point(0, 0)
        Dim OldPoint As PointF = New Point(0, 0)

        xmin = pathLines.PathPoints(0).X
        xmax = pathLines.PathPoints(0).X
        ymin = pathLines.PathPoints(0).Y
        ymax = pathLines.PathPoints(0).Y

        For x1 As Integer = 0 To UBound(pathLines.PathPoints)
            If pathLines.PathPoints(x1).X < xmin Then
                xmin = pathLines.PathPoints(x1).X

            End If
            If pathLines.PathPoints(x1).X > xmax Then
                xmax = pathLines.PathPoints(x1).X

            End If
            If pathLines.PathPoints(x1).Y < ymin Then
                ymin = pathLines.PathPoints(x1).Y

            End If
            If pathLines.PathPoints(x1).Y > ymax Then
                ymax = pathLines.PathPoints(x1).Y

            End If

        Next

        Dim xwidth As Single = ((xmax - xmin))
        Dim ywidth As Single = ((ymax - ymin))

        ' Find the centre point of the annotation
        CPoint = New PointF(((xwidth / 2)) + xmin, ((ywidth / 2)) + ymin)

        Dim aAngle As Single = 0
        Dim nChngY As Single = 0
        Dim nChngX As Single = 0
        Dim nChng As Single = 0

        Dim nPercChng As Double = (PercentageChange / 100)
        Dim xPoint As Single = 0
        Dim yPoint As Single = 0

        Dim TPoint(UBound(pathLines.PathPoints)) As PointF
        Dim Npoint As PointF = Nothing

        Label1.Text = ""

        For x1 As Integer = 0 To UBound(pathLines.PathPoints)

            OldPoint = New PointF((pathLines.PathPoints(x1).X), (pathLines.PathPoints(x1).Y))

            aAngle = CSng(Math.Atan2((OldPoint.Y - CPoint.Y), (OldPoint.X - CPoint.X)))

            ' get length of Hypotenuse
            nChngX = CSng(Math.Pow((CPoint.X - OldPoint.X), 2))
            nChngY = CSng(Math.Pow((CPoint.Y - OldPoint.Y), 2))
            nChng = CSng((Math.Sqrt((nChngX + nChngY))))

            ' get percentage changed based on length of Hypotenuse
            Dim nChngPc As Double = nChng * nPercChng
            xPoint = CSng((Math.Cos(aAngle) * nChngPc))
            yPoint = CSng(CSng((Math.Sin(aAngle) * nChngPc)))

            If OldPoint.X > (CPoint.X) Then
                ' add
                xPoint = Math.Abs(xPoint)
            Else
                ' sub
                xPoint = Math.Abs(xPoint)
                xPoint = 0 - xPoint
            End If


            If OldPoint.Y > (CPoint.Y) Then
                ' add
                yPoint = Math.Abs(yPoint)
            Else
                ' sub
                yPoint = Math.Abs(yPoint)
                yPoint = 0 - yPoint
            End If

            Dim X1a As Single, Y1a As Single, X2a As Single, Y2a As Single

            If Increase = True Then
                'larger
                X1a = ((OldPoint.X + (xPoint)))
                Y1a = (OldPoint.Y + (yPoint))
            Else
                'smaller
                X1a = ((OldPoint.X - (xPoint)))
                Y1a = (OldPoint.Y - (yPoint))
            End If

            Dim r As Double = Math.Atan(Y1a / X1a)

            ' get length of Hypotenuse
            nChngX = CSng(Math.Pow((CPoint.X - X1a), 2))
            nChngY = CSng(Math.Pow((CPoint.Y - Y1a), 2))
            nChng = CSng((Math.Sqrt((nChngX + nChngY))))

            r = ((Math.PI / 180) * (nChng))
            Dim ROT As Single = CSng(((Math.PI / 180) * RotatePerc))
            r = nChng

            X2a = CSng((r * Cos(ROT) * Cos(aAngle)) - (r * Sin(ROT) * Sin(aAngle)))
            Y2a = CSng((r * Sin(ROT) * Cos(aAngle)) + (r * Cos(ROT) * Sin(aAngle)))

            X2a = X2a + CPoint.X
            Y2a = Y2a + CPoint.Y

            Npoint = New PointF(CInt((X2a)), CInt((Y2a)))
            TPoint(x1) = Npoint
            Label1.Text = Label1.Text + "(" + Npoint.X.ToString + "," + Npoint.Y.ToString + ") - "

        Next

        pathLinesStart = New GraphicsPath
        pathLinesStart.AddLines(TPoint)

    End Sub

End Class
Attached 2 images: Bad dots & Good dots

Bad:
The picture shows a path line that has dots that clash at the start and end of the path line – NOT GOOD
Attached Images
File Type: jpg Bad.jpg (55.3 KB, 5 views)
File Type: jpg good.jpg (40.9 KB, 5 views)
Attached Files
File Type: zip DottedLine.zip (72.3 KB, 6 views)

Last edited by Flyguy; 04-13-2012 at 02:09 AM.
Reply With Quote
  #2  
Old 04-13-2012, 07:03 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default dot collisions involving poitns and lines

Quote:
This is very easy to do using “DrawPath” and defining points for the path and using a pen defined as dots.
It may be easy but it's not the way I would do it.

You need to have finer control over the placement of the dots.

Do you know there is a:
GraphicsPath.GetPathPoints method?

Another way --
From this call:
"pathLinesStart.AddLines(TPoint)"
..it looks like you are already creating an array of lines from points
(although the AddLines code isn't shown)

If you use just an array of lines instead of a path then you can
space the endpoints of the lines to prevent dot collisions.
Reply With Quote
  #3  
Old 04-16-2012, 09:27 AM
passel's Avatar
passelProblem drawing dotted path lines, with even dots along the path line passel is offline
Sinecure Expert

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

surfR2911, AddLines is a method of the GraphicsPath object, so I'm not sure what code isn't shown. The TPoint array is set up to defined the multiple lines in a figure and passed to the AddLines method. There isn't any additional code involved in that.

coolpjmartin,
If you are going to need arbitrarily spaced dots to aline to a given figure, then you are going to have to calculated the perimeter distance, divide by the desired spacing, then create a custom "Dot Pattern" ("pen.DashPattern =" method) to fill that perimeter evenly so that the end points align.
Good luck, let us know how it turns out.

{edit:}
If you could ensure that the length of a line is a multiple of your pen width, then the dot pattern should stay align as the default spacing is going to be a dot (dash actually) of one penWidth in length, followed by a space one penWidth in length.

But, as an example of one way to change the spacing (in this case increasing the space between dots to align to the corners of your example square. You could also decrease the space, which would probably look better for smaller figures) to align dots to all four corners of your square, using the example code you posted, here is a modified Panel1_Paint to handle this case.
Code:
  Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint

    Dim p As Pen = New Pen(Color.Black, 5)
    p.LineJoin = LineJoin.Round
    p.EndCap = LineCap.Round
    p.StartCap = LineCap.Round

    Dim g As Graphics = e.Graphics

    '  p.DashStyle = DashStyle.Dot
    p.DashCap = DashCap.Round

    'We want to increase the space between dots so the dots will align to the corners of the square
    '
    Dim LenOfOneSide As Single = pathLinesStart.PathPoints(1).X - pathLinesStart.PathPoints(0).X  'length of one side of square
    'numOfSpace is the number of spaces between the dots before the last dot drawn on a line.
    Dim numOfSpace As Single = Int(LenOfOneSide / 10)  '10 = 2*penWidth, which is our standard dot spacing (equal size dot and space between dots)
    Dim extraSpace As Single = (LenOfOneSide / 10) - numOfSpace 'should be a number from 0 to 1, indicating a percentage of extra dot space
    Dim spreadSpace As Single = (extraSpace / numOfSpace) * 2.0F 'Spread the extra space across the number of spaces (but don't increase dot size so *2)
    spreadSpace = spreadSpace + 1  'the default space is 1 unit, so we're adding the extra spread space to that 1 unit

    Dim dashVals() As Single = {1.0F, spreadSpace}   'the dot is left at 1.0, extra padding is in the spaces to align dots
    p.DashPattern = dashVals                         'Set the DashPattern to our customized pattern

    g.InterpolationMode = InterpolationMode.HighQualityBicubic
    g.SmoothingMode = SmoothingMode.HighQuality
    p.Color = Color.Red
    g.DrawPath(p, pathLinesStart)
    g.DrawPath(Pens.Black, pathLinesStart)

  End Sub
Of course, depending on what you are doing, it looks like it would be a lot less work to not have to recalculated and modified the points in your paths to manually scale them up or rotate them, of reposition them.
You can just use transforms to scale, rotate, position your coordinate system before you draw the path, leaving the path data itself unmodified, so you don't get creeping distortions in your path due to repeated modification of the data itself.
If you need to keep the pen size the same when you scale using transforms, you can define a new pen using a width the inverse of your scale so that it always draws the same width regardless of scale.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 04-16-2012 at 02:01 PM.
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
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
 
Problem drawing dotted path lines, with even dots along the path line
Problem drawing dotted path lines, with even dots along the path line
 
-->