2 Replies - 1379 Views - Last Post: 12 April 2012 - 03:55 PM Rate Topic: -----

#1 coolpjmartin  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 20-February 09

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

Posted 12 April 2012 - 02:48 PM

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.

Posted Image

Bad:
The picture shows a path line that has dots that clash at the start and end of the path line – NOT GOOD

Posted Image





Any help much appreciated

Thanks




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:

Dotted Line 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 File(s)


This post has been edited by AdamSpeight2008: 12 April 2012 - 02:50 PM
Reason for edit:: Please use the CODE TAGS for for code, next time


Is This A Good Question/Topic? 0
  • +

Replies To: Problem drawing dotted path lines, with even dots along the path

#2 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 13657
  • View blog
  • Posts: 54,507
  • Joined: 12-June 08

Re: Problem drawing dotted path lines, with even dots along the path

Posted 12 April 2012 - 02:57 PM

I'm a bit confused - are you asking for help or offering a tutorial?

If it's the former then check out this tutorial I did a while back. You can specify the pen's 'draw style' to be dashed, dotted, or what ever.

http://www.dreaminco...bberband-shape/

http://msdn.microsof....dashstyle.aspx
Was This Post Helpful? 0
  • +
  • -

#3 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1162
  • View blog
  • Posts: 4,444
  • Joined: 02-July 08

Re: Problem drawing dotted path lines, with even dots along the path

Posted 12 April 2012 - 03:55 PM

Why not draw the four corners using a Rectangle and it's corner locations and then come up with a function that tell how many dots based on the length of a leg of the rectangle then evenly space and draw them. Also be sure to dispose all Pens, Brushes, GraphicsPaths when you create them - a Using/End Using block works great.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1