Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Math


Public Class Form1
    Const Ra As Single = PI / 180
    Const Da As Single = 180 / PI
    Dim myPen As Pen, myGraphics As Graphics, myBmp As Bitmap, myBmpGraphics As Graphics
    Dim ptsOrg() As PointF
    Dim xLeft As Single, yTop As Single, xRight As Single, yBottom As Single
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ReDim ptsOrg(3)
        ptsOrg(0) = New PointF(-9.1, 7)
        ptsOrg(1) = New PointF(4, 5)
        ptsOrg(2) = New PointF(5, 2)
        ptsOrg(3) = New PointF(0.5, -8.7)
    End Sub

    Private Sub ButPathDraw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        myPen = Pens.Green
        myGraphics = PictureBox1.CreateGraphics
        myGraphics.DrawLine(myPen, 0, 0, 30, 20)
        myGraphics.DrawEllipse(myPen, 20, 20, 20, 40)
        myGraphics.DrawBezier(myPen, 30, 60, 70, 60, 50, 30, 100, 10)
        myPen = Pens.Red
        Dim myGraphicsPath = New GraphicsPath
        myGraphicsPath.AddLine(0, 0, 30, 20)
        myGraphicsPath.AddEllipse(20, 20, 20, 40)
        myGraphicsPath.AddBezier(30, 60, 70, 60, 50, 30, 100, 10)
        myGraphics.DrawPath(myPen, myGraphicsPath)
    End Sub
    Private Sub PtsData_Bounds(ByVal canvas As PictureBox, ByVal ptsOrg() As PointF, ByRef ptsApi() As Point)
        Dim xMin As Single, yMin As Single, xMax As Single, yMax As Single
        Dim npt As Integer = UBound(ptsOrg)

        xMin = 999999
        yMin = 999999
        xMax = -999999
        yMax = -999999
        For i As Integer = 0 To npt
            If ptsOrg(i).X >= xMax Then xMax = ptsOrg(i).X
            If ptsOrg(i).Y >= yMax Then yMax = ptsOrg(i).Y
            If ptsOrg(i).X < xMin Then xMin = ptsOrg(i).X
            If ptsOrg(i).Y < yMin Then yMin = ptsOrg(i).Y
        Next i

        Dim xOffset As Single = Round(Max(Abs(xMax), Abs(xMin)) * 0.45, 2)
        Dim yOffset As Single = Round(Max(Abs(yMax), Abs(yMin)) * 0.45, 2)
        xLeft = Round(xMin, 2) - xOffset
        xRight = Round(xMax, 2) + xOffset
        yTop = Round(yMax, 2) + yOffset
        yBottom = Round(yMin, 2) - yOffset
        For i As Integer = 0 To npt
            ReDim Preserve ptsApi(i)
            ptsApi(i) = ptConvertToPix(canvas, CDbl(xLeft), CDbl(xRight), CDbl(yTop), CDbl(yBottom), ptsOrg(i))
        Next i

    End Sub
    Private Sub ButSpline_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        DrawSpline(PictureBox1, Nothing, ptsOrg)

    End Sub
    Private Sub DrawSpline(ByVal Canvas As PictureBox, ByVal mPen As Pen, ByVal ptsOrgIn() As PointF)
        Dim PtsApi() As Point
        Call PtsData_Bounds(Canvas, ptsOrgIn, PtsApi)
        myBmp = New Bitmap(Canvas.Size.Width, Canvas.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        myGraphics = Canvas.CreateGraphics
        Dim tension As Single, MyPen As Pen
        For i As Integer = 0 To UBound(PtsApi)
            myGraphics.DrawEllipse(Pens.Blue, PtsApi(i).X - 5, PtsApi(i).Y - 5, 10, 10)
        Next

        For i As Integer = 0 To 5

            If IsNothing(mPen) Then
                Select Case i
                    Case 0
                        MyPen = New Pen(Color.Red, 1)
                    Case 1
                        MyPen = New Pen(Color.Green, 1)
                    Case 2
                        MyPen = New Pen(Color.Blue, 1)
                    Case 3
                        MyPen = New Pen(Color.Cyan, 1)
                    Case 4
                        MyPen = New Pen(Color.Violet)
                    Case 5
                        MyPen = New Pen(Color.Magenta)
                End Select

            End If

            myGraphics.DrawCurve(MyPen, PtsApi, i * 0.2)
        Next

    End Sub
    Private Sub DrawBezierA(ByVal Canvas As PictureBox, ByVal mPen As Pen, ByVal ptsOrgIn() As PointF)
        Dim PtsApi() As Point
        Call PtsData_Bounds(Canvas, ptsOrgIn, PtsApi)
        myBmp = New Bitmap(Canvas.Size.Width, Canvas.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        myGraphics = Canvas.CreateGraphics
        Dim tension As Single, MyPen As Pen
        For i As Integer = 0 To UBound(PtsApi)
            myGraphics.DrawEllipse(Pens.Blue, PtsApi(i).X - 5, PtsApi(i).Y - 5, 10, 10)
        Next

        If IsNothing(mPen) Then
            MyPen = New Pen(Color.Red, 1)
        Else
            MyPen = mPen
        End If

        myGraphics.DrawBeziers(MyPen, PtsApi)


    End Sub
    Private Sub Butbesier_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        myPen = Pens.Green
        Dim noSeg As Integer = 5
        Dim offset As Integer = 0
        myGraphics = PictureBox1.CreateGraphics

        Dim pts(9) As PointF
        pts(0) = New PointF(20, 30)
        pts(1) = New PointF(70, 90)
        pts(2) = New PointF(120, 98)
        pts(3) = New PointF(150, 190)
        pts(4) = New PointF(170, 200)
        pts(5) = New PointF(200, 298)
        pts(6) = New PointF(350, 390)
        pts(7) = New PointF(170, 130)
        pts(8) = New PointF(220, 198)
        pts(9) = New PointF(350, 90)
        For i As Integer = 0 To pts.Length - 1
            ListBox1.Items.Add("org x=" & pts(i).X & "y=" & pts(i).Y)
            myGraphics.DrawEllipse(Pens.Green, pts(i).X - 5, pts(i).Y - 5, 10, 10)
        Next
        myGraphics.DrawBeziers(myPen, pts)

        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Blue
        myGraphicsPath.AddBeziers(pts)
        myGraphics.DrawPath(myPen, myGraphicsPath)
        myGraphicsPath.Flatten()

        Dim ptspath() As PointF
        ptspath = myGraphicsPath.PathPoints

        For i As Integer = 0 To ptspath.Length - 1
            myGraphics.DrawEllipse(Pens.Blue, ptspath(i).X - 2, ptspath(i).Y - 2, 4, 4)
            ListBox1.Items.Add("spline x=" & ptspath(i).X & "y=" & ptspath(i).Y)
        Next
        Dim ptsBaseLine(1) As PointF
        ptsBaseLine(0) = New PointF(300, 400)
        ptsBaseLine(1) = New PointF(400, 400)
        myGraphics.DrawLine(Pens.BlueViolet, ptsBaseLine(0), ptsBaseLine(1))
        Dim angsPt() As Single, lDist() As Double
        Dim delX1 As Double = ptsBaseLine(1).X - ptsBaseLine(0).X
        Dim delY1 As Double = ptsBaseLine(1).Y - ptsBaseLine(0).Y
        Dim L1 As Double = Sqrt(delX1 * delX1 + delY1 * delY1)
        For i As Integer = 0 To ptspath.Length - 1
            Dim delX2 As Double = ptspath(i).X - ptsBaseLine(0).X
            Dim delY2 As Double = ptspath(i).Y - ptsBaseLine(0).Y
            Dim L2 As Double = Sqrt(delX2 * delX2 + delY2 * delY2)
            ReDim Preserve angsPt(i), lDist(i)
            angsPt(i) = Acos((delX1 * delX2 + delY1 * delY2) / L1 / L2) * 180 / PI
            lDist(i) = L2
            ListBox1.Items.Add(" pt_ " & i & " ;X= " & Round(ptspath(i).X, 5) & " ;Y= " & Round(ptspath(i).Y, 5) & " ;ldist= " & Round(lDist(i), 5) & " ;ang= " & Round(angsPt(i), 5))
            myGraphics.DrawLine(Pens.Magenta, ptsBaseLine(0), ptspath(i))
        Next


    End Sub

    Private Sub ButptsOnSpline_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point

        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next


        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        Dim tension As Single = 0.5
        myGraphicsPath.AddCurve(ptsApi, 0.5)
        Dim rect As RectangleF = myGraphicsPath.GetBounds
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        Dim count As Integer = 0
        For j As Integer = CInt(rect.Y) + 2 To CInt(rect.Height + rect.Y) - 2

            For i As Integer = CInt(rect.X) + 2 To CInt(rect.Width + rect.X) - 2
                If myBmp.GetPixel(i, j) <> colorBase Then

                    ReDim ptsUser(count)
                    ptsUser(count) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, i, j)
                    ListBox1.Items.Add(" x=" & i & " ;y=" & j & " ;xuser= " & ptsUser(count).X & " ;yuser=" & ptsUser(count).Y)
                    count += 1
                End If
            Next i
            ' myBmpGraphics.DrawLine(Pens.Green, CInt(rect.X), yGiven, CInt(rect.Width) + CInt(rect.X), yGiven)
        Next j
        PictureBox1.Image = myBmp
    End Sub

    Private Sub SplineToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplineToolStripMenuItem.Click
        DrawSpline(PictureBox1, Nothing, ptsOrg)
    End Sub

    Private Sub BezerCurveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BezerCurveToolStripMenuItem.Click
        DrawBezierA(PictureBox1, Nothing, ptsOrg)
    End Sub

    Private Sub SPlineToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SPlineToolStripMenuItem1.Click
        DrawSpline_Flatten()
    End Sub
    Private Sub DrawSpline_Flatten()
        Dim ptspath() As PointF
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point

        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        Dim tension As Single = 0.5
        myGraphicsPath.AddCurve(ptsApi, 0.5)
        Dim rect As RectangleF = myGraphicsPath.GetBounds
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        Dim count As Integer = 0
        myGraphicsPath.Flatten()

        ptspath = myGraphicsPath.PathPoints
        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawEllipse(Pens.Blue, ptspath(i).X - 2, ptspath(i).Y - 2, 4, 4)
            ListBox1.Items.Add("spline x=" & ptspath(i).X & "y=" & ptspath(i).Y)
        Next
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 100)
        ptsBaseline(1) = New PointF(200, 100)

        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawLine(Pens.Green, ptsBaseline(0), ptspath(i))
            ReDim Preserve ptsUser(i)
            ptsUser(i) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, CInt(ptspath(i).X), CInt(ptspath(i).Y))
            ListBox1.Items.Add("ptUser on path :x=" & ptsUser(i).X & ";y= " & ptsUser(i).Y)
        Next
        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double

        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)
        myBmpGraphics.DrawLine(New Pen(Color.Magenta, 2), ptsBaseline(0), ptsBaseline(1))
        PictureBox1.Image = myBmp
    End Sub
    Private Sub SplineToolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplineToolStripMenuItem2.Click
        DrawSpline_getPixel()
    End Sub

    Private Sub DrawSpline_getPixel()
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point

        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        Dim tension As Single = 0.5
        myGraphicsPath.AddCurve(ptsApi, 0.5)
        Dim rect As RectangleF = myGraphicsPath.GetBounds
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        '
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 100)
        ptsBaseline(1) = New PointF(200, 100)
        Dim count As Integer = 0, ptsUserApi() As Point
        For j As Integer = CInt(rect.Y) + 2 To CInt(rect.Height + rect.Y) - 2
            For i As Integer = CInt(rect.X) + 2 To CInt(rect.Width + rect.X) - 2
                If myBmp.GetPixel(i, j) <> colorBase Then
                    ReDim Preserve ptsUser(count), ptsUserApi(count)
                    ptsUserApi(count) = New Point(i, j)
                    ptsUser(count) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, i, j)
                    ListBox1.Items.Add(" x=" & i & " ;y=" & j & " ;xuser= " & ptsUser(count).X & " ;yuser=" & ptsUser(count).Y)
                    count += 1
                End If
            Next i
        Next j

        For i As Integer = 0 To UBound(ptsUserApi) Step 10
            myBmpGraphics.DrawLine(New Pen(Color.Green, 1), ptsBaseline(0), ptsUserApi(i))
        Next

        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double
        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)
        myBmpGraphics.DrawLine(New Pen(Color.Magenta, 2), ptsBaseline(0), ptsBaseline(1))
        PictureBox1.Image = myBmp

    End Sub
    Private Sub Stake(ByVal canvas As PictureBox, ByVal ptsPathUser() As PointF, ByVal ptsBaseLineAPI() As PointF, ByRef Ldist() As Double, ByRef angsIncl() As Double, ByRef angsPtI() As Double)

        Dim ptsBaseUser(0 To 1) As PointF
        For i As Integer = 0 To 1
            ptsBaseUser(i) = ptConvertToUser(canvas, xLeft, xRight, yTop, yBottom, ptsBaseLineAPI(i).X, ptsBaseLineAPI(i).Y)
            ListBox1.Items.Add("pt_ " & i & " ;baseLine= " & ptsBaseUser(i).X & ";" & ptsBaseUser(i).Y)
        Next

        Dim delX1 As Double = ptsBaseUser(1).X - ptsBaseUser(0).X
        Dim delY1 As Double = ptsBaseUser(1).Y - ptsBaseUser(0).Y
        Dim L1 As Double = Sqrt(delX1 * delX1 + delY1 * delY1)
        For i As Integer = 0 To ptsPathUser.Length - 1
            Dim delX2 As Double = CDbl(ptsPathUser(i).X - ptsBaseUser(0).X)
            Dim delY2 As Double = CDbl(ptsPathUser(i).Y - ptsBaseUser(0).Y)
            Dim L2 As Double = Sqrt(delX2 * delX2 + delY2 * delY2)
            ReDim Preserve angsIncl(i), Ldist(i), angsPtI(i)
            angsIncl(i) = Acos((delX1 * delX2 + delY1 * delY2) / L1 / L2) * 180 / PI
            angsPtI(i) = Atan2(delY2 - delY1, delX2 - delX1) * 180 / PI
            If angsPtI(i) < 0.0F Then angsPtI(i) = angsPtI(i) + 360.0
            Ldist(i) = L2
            ListBox1.Items.Add(" pt_ " & i & " ;X= " & Round(ptsPathUser(i).X, 5) & " ;Y= " & Round(ptsPathUser(i).Y, 5) & " ;ldist= " & Round(Ldist(i), 5) & " ;ang= " & Round(angsIncl(i), 5) & " ;angPtI= " & Round(angsPtI(i), 5))
        Next

    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim ptUser As PointF
        ptUser = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, CInt(e.X), CInt(e.Y))
        Lblxy.Text = " X_pix= " & e.X & " Y_pix= " & e.Y & " ;xuser= " & Round(ptUser.X, 5) & ";yuser= " & Round(ptUser.Y, 5)

    End Sub
    Public Function ptConvertToUser(ByVal canvas As PictureBox, ByVal xLeft As Single, ByVal xRight As Single, ByVal yTop As Single, ByVal yBottom As Single, _
    ByVal xPix As Integer, ByVal yPix As Integer) As PointF
        ptConvertToUser.X = CSng(xRight - xLeft) / CSng(canvas.ClientSize.Width) * xPix + xLeft
        ptConvertToUser.Y = CSng(yBottom - yTop) / CSng(canvas.ClientSize.Height) * yPix + yTop
    End Function
    Public Function ptConvertToPix(ByVal canvas As PictureBox, ByVal xLeft As Double, ByVal xRight As Double, ByVal yTop As Double, ByVal yBottom As Double, _
     ByVal xUser As Single, ByVal yUser As Single) As PointF
        ptConvertToPix.X = xUser * CSng(canvas.ClientSize.Width) / (xRight - xLeft) - xLeft * CSng(canvas.ClientSize.Width) / (xRight - xLeft)
        ptConvertToPix.Y = yUser * CSng(canvas.ClientSize.Height) / (yBottom - yTop) - yTop * CSng(canvas.ClientSize.Height) / (yBottom - yTop)
    End Function
    Public Function ptConvertToUser(ByVal canvas As PictureBox, ByVal xLeft As Single, ByVal xRight As Single, ByVal yTop As Single, ByVal yBottom As Single, _
        ByVal ptPix As Point) As PointF
        ptConvertToUser.X = CSng(xRight - xLeft) / CSng(canvas.ClientSize.Width) * ptPix.X + xLeft
        ptConvertToUser.Y = CSng(yBottom - yTop) / CSng(canvas.ClientSize.Height) * ptPix.Y + yTop
    End Function
    Public Function ptConvertToPix(ByVal canvas As PictureBox, ByVal xLeft As Double, ByVal xRight As Double, ByVal yTop As Double, ByVal yBottom As Double, _
     ByVal PtUser As PointF) As Point
        ptConvertToPix.X = PtUser.X * CSng(canvas.ClientSize.Width) / (xRight - xLeft) - xLeft * CSng(canvas.ClientSize.Width) / (xRight - xLeft)
        ptConvertToPix.Y = PtUser.Y * CSng(canvas.ClientSize.Height) / (yBottom - yTop) - yTop * CSng(canvas.ClientSize.Height) / (yBottom - yTop)
    End Function

    Private Sub BezierCurveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BezierCurveToolStripMenuItem.Click
        DrawBezier_Flatten()
    End Sub
    Private Sub DrawBezier_Flatten()
        Dim ptspath() As PointF
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point

        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        myGraphicsPath.AddBeziers(ptsApi)
        Dim rect As RectangleF = myGraphicsPath.GetBounds
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        Dim count As Integer = 0
        myGraphicsPath.Flatten()

        ptspath = myGraphicsPath.PathPoints
        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawEllipse(Pens.Blue, ptspath(i).X - 2, ptspath(i).Y - 2, 4, 4)
            ListBox1.Items.Add("spline x=" & ptspath(i).X & "y=" & ptspath(i).Y)
        Next
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 100)
        ptsBaseline(1) = New PointF(200, 100)

        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawLine(Pens.Blue, ptsBaseline(0), ptspath(i))
            ReDim Preserve ptsUser(i)
            ptsUser(i) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, CInt(ptspath(i).X), CInt(ptspath(i).Y))
            ListBox1.Items.Add("ptUser on path :x=" & ptsUser(i).X & ";y= " & ptsUser(i).Y)
        Next
        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double

        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)
        myBmpGraphics.DrawLine(New Pen(Color.Magenta, 2), ptsBaseline(0), ptsBaseline(1))
        PictureBox1.Image = myBmp
    End Sub
    Private Sub DrawBezier_getPixel()
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point

        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
        Next
        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        myGraphicsPath.AddBeziers(ptsApi)
        Dim rect As RectangleF = myGraphicsPath.GetBounds
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        Dim count As Integer = 0, ptsUserApi() As Point
        For j As Integer = CInt(rect.Y) + 2 To CInt(rect.Height + rect.Y) - 2

            For i As Integer = CInt(rect.X) + 2 To CInt(rect.Width + rect.X) - 2
                If myBmp.GetPixel(i, j) <> colorBase Then
                    ReDim Preserve ptsUser(count), ptsUserApi(count)
                    ptsUserApi(count) = New Point(i, j)
                    ptsUser(count) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, i, j)
                    ListBox1.Items.Add(" x=" & i & " ;y=" & j & " ;xuser= " & ptsUser(count).X & " ;yuser=" & ptsUser(count).Y)
                    count += 1
                End If
            Next i
        Next j
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 100)
        ptsBaseline(1) = New PointF(200, 100)
        For i As Integer = 0 To UBound(ptsUserApi) Step 10
            myBmpGraphics.DrawLine(New Pen(Color.Green, 1), ptsBaseline(0), ptsUserApi(i))
        Next
        myBmpGraphics.DrawLine(Pens.Magenta, ptsBaseline(0), ptsBaseline(1))
        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double
        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)

        For i As Integer = 0 To ptsApi.Length - 1
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        PictureBox1.Image = myBmp
    End Sub
    Private Sub BezierCurveToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BezierCurveToolStripMenuItem1.Click
        DrawBezier_getPixel()
    End Sub

    Private Sub OpenEllipseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenEllipseToolStripMenuItem.Click
        DrawEllipse_Flatten()
    End Sub
    Private Sub DrawEllipse_Flatten()
        Dim ptspath() As PointF
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point
        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        'myBmpGraphics.RotateTransform(30)

        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        Dim rect As RectangleF, ptsLineLimit() As PointF
        Call getLineLimits(ptsApi, ptsLineLimit)
        rect.X = ptsLineLimit(0).X
        rect.Y = ptsLineLimit(0).Y
        rect.Width = Abs(ptsLineLimit(0).X - ptsLineLimit(1).X)
        rect.Height = Abs(ptsLineLimit(0).Y - ptsLineLimit(1).Y)
        ListBox1.Items.Add("org x=" & rect.X & ";y= " & rect.Y & " ;api W= " & rect.Width & " ;H= " & rect.Height)
        myBmpGraphics.DrawRectangle(New Pen(Color.Green, 1), CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
        'myBmpGraphics.DrawEllipse(Pens.Green, rect)
        myGraphicsPath.AddArc(rect, 30, 270)
        PictureBox1.Image = myBmp
        myBmpGraphics.DrawPath(myPen, myGraphicsPath)
        Dim count As Integer = 0
        myGraphicsPath.Flatten()
        ptspath = myGraphicsPath.PathPoints
        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawEllipse(Pens.Blue, ptspath(i).X - 2, ptspath(i).Y - 2, 4, 4)
            ListBox1.Items.Add("Ellipse x=" & ptspath(i).X & "y=" & ptspath(i).Y)
        Next
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 100)
        ptsBaseline(1) = New PointF(200, 100)

        For i As Integer = 0 To ptspath.Length - 1
            myBmpGraphics.DrawLine(Pens.Green, ptsBaseline(0), ptspath(i))
            ReDim Preserve ptsUser(i)
            ptsUser(i) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, CInt(ptspath(i).X), CInt(ptspath(i).Y))
            ListBox1.Items.Add("ptUser on path :x=" & ptsUser(i).X & ";y= " & ptsUser(i).Y)
        Next

        'pointArray = Array.ConvertAll(pointArray, Function(p) Rotate(p, t))
        'Dim t As Single = Math.PI * 90 / 180
        'pointsArray = Array.ConvertAll(pointsArray, Function(p) Rotate(p, t))
        'Dim ptsArray() As Array
        'ptsarray=Array.ConvertAll(ptsarray,function(pt),rotate(pt,30*Ra))
        'For i = 0 To UBound(ptsUser)
        'ptsUser(i) = Rotate(ptsUser(i), 30)
        'ListBox1.Items.Add("rotated,ptUser on path :x=" & ptsUser(i).X & ";y= " & ptsUser(i).Y)
        'Next

        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double
        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)
        myBmpGraphics.DrawLine(New Pen(Color.Magenta, 2), ptsBaseline(0), ptsBaseline(1))
        PictureBox1.Image = myBmp
    End Sub
    Private Sub DrawEllipseInclind_Flatten()
        ReDim ptsOrg(3)
        ptsOrg(0) = New PointF(-5.1, 5)
        ptsOrg(1) = New PointF(4, 5)
        ptsOrg(2) = New PointF(5, 2)
        ptsOrg(3) = New PointF(0.5, -4.7)
        Dim ptspath() As PointF
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point
        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        For i As Integer = 0 To ptsApi.Length - 1
            ListBox1.Items.Add("org x=" & ptsOrg(i).X & ";y= " & ptsOrg(i).Y & " ;api x= " & ptsApi(i).X & " ;y= " & ptsApi(i).Y)
            'myBmpGraphics.DrawEllipse(Pens.Blue, ptsApi(i).X - 4, ptsApi(i).Y - 4, 8, 8)
        Next
        myBmpGraphics.RotateTransform(10)
        Dim myGraphicsPath = New GraphicsPath
        myPen = Pens.Red
        Dim rect As RectangleF
        Dim ptsLineLimit(1) As PointF
        Call getLineLimits(ptsApi, ptsLineLimit)
        rect.X = ptsLineLimit(0).X
        rect.Y = ptsLineLimit(0).Y
        rect.Width = Abs(ptsLineLimit(0).X - ptsLineLimit(1).X)
        rect.Height = Abs(ptsLineLimit(0).Y - ptsLineLimit(1).Y)
        myBmpGraphics.DrawArc(Pens.Green, rect, 30, 270)
        myBmpGraphics.ResetTransform()

        Dim count As Integer = 0, ptsUserApi() As Point
        For j As Integer = 1 To CInt(rect.Height) - 1
            For i As Integer = 1 To CInt(rect.Width) - 1
                If myBmp.GetPixel(i, j) <> colorBase Then
                    ReDim Preserve ptsUser(count), ptsUserApi(count)
                    ptsUserApi(count) = New Point(i, j)
                    ptsUser(count) = ptConvertToUser(PictureBox1, xLeft, xRight, yTop, yBottom, i, j)
                    ListBox1.Items.Add(" x=" & i & " ;y=" & j & " ;xuser= " & ptsUser(count).X & " ;yuser=" & ptsUser(count).Y)
                    count += 1
                End If
            Next i
        Next j
        Dim ptsBaseline(1) As PointF
        ptsBaseline(0) = New PointF(100, 200)
        ptsBaseline(1) = New PointF(200, 200)
        For i As Integer = 0 To UBound(ptsUser) Step 10
            myBmpGraphics.DrawLine(New Pen(Color.Green, 1), ptsBaseline(0), ptsUserApi(i))
        Next

      
        Dim lDist() As Double, angsIncl() As Double, angsPtI() As Double
        Call Stake(PictureBox1, ptsUser, ptsBaseline, lDist, angsIncl, angsPtI)
        myBmpGraphics.DrawLine(New Pen(Color.Magenta, 2), ptsBaseline(0), ptsBaseline(1))
        PictureBox1.Image = myBmp
    End Sub
    Private Sub getLineLimits(ByVal PtsIn() As PointF, ByRef ptsLineLimit() As PointF)
        Dim npt As Integer = UBound(PtsIn)
        Dim xMin As Single = 99999
        Dim yMin As Single = 99999
        Dim xMax As Single = -99999
        Dim yMax As Single = -99999
        For i = 0 To npt
            If PtsIn(i).X >= xMax Then xMax = PtsIn(i).X
            If PtsIn(i).Y >= yMax Then yMax = PtsIn(i).Y
            If PtsIn(i).X < xMin Then xMin = PtsIn(i).X
            If PtsIn(i).Y < yMin Then yMin = PtsIn(i).Y
        Next
        ReDim ptsLineLimit(1)
        ptsLineLimit(0) = New PointF(xMin, yMin)
        ptsLineLimit(1) = New PointF(xMax, yMax)

    End Sub
    Private Sub getLineLimits(ByVal PtsIn() As Point, ByRef ptsLineLimit() As PointF)
        Dim npt As Integer = UBound(PtsIn)
        Dim xMin As Single = 99999
        Dim yMin As Single = 99999
        Dim xMax As Single = -99999
        Dim yMax As Single = -99999
        For i = 0 To npt
            If PtsIn(i).X >= xMax Then xMax = PtsIn(i).X
            If PtsIn(i).Y >= yMax Then yMax = PtsIn(i).Y
            If PtsIn(i).X < xMin Then xMin = PtsIn(i).X
            If PtsIn(i).Y < yMin Then yMin = PtsIn(i).Y
        Next
        ReDim ptsLineLimit(1)
        ptsLineLimit(0) = New PointF(xMin, yMin)
        ptsLineLimit(1) = New PointF(xMax, yMax)

    End Sub
    Private Function Rotate(ByVal Pt As Point, ByVal theta As Single) As Point
        Dim rx As Integer = CInt((Pt.X * Math.Cos(theta * Ra)) - (Pt.Y * Math.Sin(theta * Ra)))
        Dim ry As Integer = CInt((Pt.Y * Math.Cos(theta * Ra)) + (Pt.X * Math.Sin(theta * Ra)))
        Return New Point(rx, ry)
    End Function
    Private Function Rotate(ByVal pt As PointF, ByVal theta As Single) As PointF
        Dim rx As Single = CInt((pt.X * Math.Cos(theta * Ra)) - (pt.Y * Math.Sin(theta * Ra)))
        Dim ry As Single = CInt((pt.Y * Math.Cos(theta * Ra)) + (pt.X * Math.Sin(theta * Ra)))
        Return New PointF(rx, ry)
    End Function

    Private Sub OpenEllipseInclindToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        DrawEllipseInclind_Flatten()
    End Sub

    Private Sub ButComBinedDraw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButComBinedDraw.Click
        Dim ptspath() As PointF
        Dim ptsUser() As PointF
        myPen = Pens.Green
        myBmp = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        myBmpGraphics = Graphics.FromImage(myBmp)
        Dim colorBase As Color = myBmp.GetPixel(1, 1)
        Dim ptsApi() As Point
        PtsData_Bounds(PictureBox1, ptsOrg, ptsApi)
        Dim myGraphicpath As New GraphicsPath
        'myBmpGraphics.DrawCurve(New Pen(Color.Green, 4), ptsApi)
        'myBmpGraphics.DrawLine(New Pen(Color.Blue, 5), 80, 30, 220, 330)
        'GoTo 100
        myGraphicpath.AddLine(30.0F, 30.0F, 200.0F, 200.0F)
        myGraphicpath.AddCurve(ptsApi, 0)
        ' myGraphicpath.AddCurve(ptsApi, 0.5)

        myGraphicpath.AddPolygon(ptsApi)
        myBmpGraphics.DrawPath(New Pen(Color.Red, 1), myGraphicpath)

        myGraphicpath.Flatten()
        ptspath = myGraphicpath.PathPoints
        For i As Integer = 0 To UBound(ptspath)
            ListBox1.Items.Add("x= " & ptspath(i).X & ";" & ptspath(i).Y)
            myBmpGraphics.DrawEllipse(Pens.Green, ptspath(i).X, ptspath(i).Y, 1, 1)
            myBmpGraphics.DrawString(i, Me.Font, New SolidBrush(Color.Black), ptspath(i).X + 10, ptspath(i).Y)
        Next
100:    PictureBox1.Image = myBmp
    End Sub
End Class
