Profile Picture

Draw XYZ line and then draw a circle perpendicular to the line

Posted By Bruce Guthrie 14 Years Ago

Draw XYZ line and then draw a circle perpendicular to the line

Author
Message
Bruce Guthrie
Posted 14 Years Ago
View Quick Profile
Junior Member

Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)

Group: Forum Members
Last Active: 6 Years Ago
Posts: 14, Visits: 2

hello

i have a problem that i cannot quite resolve.

i have a simple XYZ Scatter line in a 3D chart, i then want to draw a circle, i use a smooth line series for this, at a point on the line, but i want the circlw to be perpendicular to the line.

 

here is some code i tried but i could never quite get the perpendicluar circle, i could get close but not perpendicular.  i am sure  it is just some basic maths that i am missing.  maybe some one out there can point out my error.

i draw a basic XYZ scatter line as follows.

' add a header label

Dim header As NLabel = NChartControl1.Labels.AddHeader("XY Scatter Line Chart")

header.TextStyle.FontStyle = New NFontStyle("Times New Roman", 18, FontStyle.Italic)

header.ContentAlignment = ContentAlignment.BottomRight

header.Location = New NPointL(New NLength(2, NRelativeUnit.ParentPercentage), New NLength(2, NRelativeUnit.ParentPercentage))

NChartControl1.Controller.Tools.Add(New NTrackballTool())

' apply predefined projection and lighting

'm_Chart.Projection.SetPredefinedProjection(PredefinedProjection.PerspectiveTilted)

'm_Chart.LightModel.SetPredefinedLightModel(PredefinedLightModel.NorthernLights)

m_Chart = NChartControl1.Charts(0)

m_Chart.Axis(StandardAxis.Depth).Visible = True

m_Chart.Enable3D = True

m_Chart.Width = 70

m_Chart.Height = 70

m_Chart.Depth = 70

NChartControl1.Controller.Selection.Add(m_Chart)

' add interlaced stripe to the Y axis

Dim linearScale As NLinearScaleConfigurator = New NLinearScaleConfigurator()

Dim stripStyle As NScaleStripStyle = New NScaleStripStyle(New NColorFillStyle(Color.Beige), Nothing, True, 0, 0, 1, 1)

stripStyle.SetShowAtWall(ChartWallType.Back, True)

stripStyle.SetShowAtWall(ChartWallType.Left, True)

stripStyle.Interlaced = True

linearScale.StripStyles.Add(stripStyle)

m_Chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = linearScale

linearScale.MajorGridStyle.SetShowAtWall(ChartWallType.Back, True)

' add the line

m_Line = CType(m_Chart.Series.Add(SeriesType.Line), NLineSeries)

m_Line.LineSegmentShape = LineSegmentShape.Line

m_Line.DataLabelStyle.Visible = False

m_Line.Legend.Mode = SeriesLegendMode.DataPoints

m_Line.InflateMargins = True

m_Line.MarkerStyle.Visible = True

m_Line.BorderStyle.Color = Color.Red

m_Line.MarkerStyle.PointShape = PointShape.Cylinder

m_Line.MarkerStyle.Width = New NLength(1.5F, NRelativeUnit.ParentPercentage)

m_Line.MarkerStyle.Height = New NLength(1.5F, NRelativeUnit.ParentPercentage)

m_Line.Name = "Line Series"

' add xy values

For i As Integer = 1 To 40 Step 5

m_Line.Values.Add(i)

m_Line.XValues.Add(i)

m_Line.ZValues.Add(i)

Next

' instruct the line series to use x values

m_Line.UseXValues = True

m_Line.UseZValues = True

 

 

then on a button click i attmept to draw my circle perpendicular to the line at point 12,12,12  with  radius of 2.  my line has an angle of 45 degrees.

 

' add the line

m_Line1 = CType(m_Chart.Series.Add(SeriesType.SmoothLine), NSmoothLineSeries)

'm_Line1.LineSegmentShape = LineSegmentShape.Line

m_Line1.DataLabelStyle.Visible = False

m_Line1.Legend.Mode = SeriesLegendMode.None

m_Line1.InflateMargins = False

m_Line1.BorderStyle.Color = Color.Blue

m_Line1.BorderStyle.Width = New NLength(3)

'm_Line1.MarkerStyle.Visible = False

m_Line1.Name = "Line Series"

' instruct the line series to use x values

m_Line1.UseXValues = True

m_Line1.UseZValues = True

Dim x As Single = 12

Dim y As Single = 12

Dim z As Single = 12

Dim r As Integer = 2

Dim inc As Integer = 45

' add xy values

For i As Integer = 0 To 360 Step 5

'm_Line1.Values.Add(y + r * Math.Sin(Math.PI / 180 * i))

m_Line1.Values.Add(y + r * Math.Sin(Math.PI / 180 * (inc + i)))

m_Line1.XValues.Add(x + r * Math.Cos(Math.PI / 180 * i))

m_Line1.ZValues.Add(z + r * Math.Cos((Math.PI / 180) * (i + 180)))

'm_Line1.ZValues.Add(z + r * Math.Sin((Math.PI / 180) * i))

 

Next

NChartControl1.Refresh()

 

 

i tried various combinations of X,Y,Z calculations but could never get the perpendicular circle.

 

Regards

Bruce

 



Bruce Guthrie
Posted 14 Years Ago
View Quick Profile
Junior Member

Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)

Group: Forum Members
Last Active: 6 Years Ago
Posts: 14, Visits: 2

i forgot to add that the line should then pass through the center of the circle with the circle being perpendicular to the line.

 

regards

Bruce.



Milen Metodiev
Posted 14 Years Ago
View Quick Profile
Forum Member

Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)Forum Member (48 reputation)

Group: Nevron Team
Last Active: 14 Years Ago
Posts: 48, Visits: 1
Hi Bruce,

Attached is some VB code that will hopefully solve your problem.

Best Regards,
Milen

----------------------------------------------------------------------------

Imports Nevron.GraphicsCore
Imports Nevron.Chart
Imports Nevron.Chart.WinForm


Public Class Form1
Dim rand As New Random

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

Dim chart As NChart = NChartControl1.Charts(0)
chart.Axis(StandardAxis.Depth).Visible = True
chart.Enable3D = True
chart.BoundsMode = BoundsMode.Fit
chart.Width = 60
chart.Height = 60
chart.Depth = 60
chart.Projection.SetPredefinedProjection(PredefinedProjection.Perspective)
chart.Wall(ChartWallType.Left).Visible = False
chart.Wall(ChartWallType.Back).Visible = False

NChartControl1.Controller.Selection.Add(chart)
NChartControl1.Controller.Tools.Add(New NTrackballTool())

Dim axisX As NAxis = chart.Axis(StandardAxis.PrimaryX)
Dim axisY As NAxis = chart.Axis(StandardAxis.PrimaryY)
Dim axisZ As NAxis = chart.Axis(StandardAxis.Depth)

axisX.View = New NRangeAxisView(New NRange1DD(-10, 50), True, True)
axisY.View = New NRangeAxisView(New NRange1DD(-10, 50), True, True)
axisZ.View = New NRangeAxisView(New NRange1DD(-10, 50), True, True)

Dim scaleX As NLinearScaleConfigurator = New NLinearScaleConfigurator()
scaleX.RoundToTickMin = False
scaleX.RoundToTickMax = False
axisX.ScaleConfigurator = scaleX

Dim scaleY As NLinearScaleConfigurator = New NLinearScaleConfigurator()
scaleY.RoundToTickMin = False
scaleY.RoundToTickMax = False
axisY.ScaleConfigurator = scaleY

Dim scaleZ As NLinearScaleConfigurator = New NLinearScaleConfigurator()
scaleZ.RoundToTickMin = False
scaleZ.RoundToTickMax = False
axisZ.ScaleConfigurator = scaleZ

CreateBaseLine(0, 0, 0, 40, 20, 35)

End Sub


Private Sub CreateBaseLine(ByVal x1 As Double, ByVal y1 As Double, ByVal z1 As Double, ByVal x2 As Double, ByVal y2 As Double, ByVal z2 As Double)
Dim chart As NChart = NChartControl1.Charts(0)

Dim line As New NLineSeries
chart.Series.Clear()
chart.Series.Add(line)

line.LineSegmentShape = LineSegmentShape.Line
line.DataLabelStyle.Visible = False
line.Legend.Mode = SeriesLegendMode.None
line.InflateMargins = False
line.UseXValues = True
line.UseZValues = True
line.FillStyle = New NColorFillStyle(Color.Crimson)
line.BorderStyle.Color = Color.Crimson
line.MarkerStyle.Visible = False
line.LineSegmentShape = LineSegmentShape.Tube
line.LineSize = New NLength(3, NRelativeUnit.ParentPercentage)

Dim marker As New NMarkerStyle
marker.Visible = True
marker.Width = New NLength(4, NRelativeUnit.ParentPercentage)
marker.Height = New NLength(4, NRelativeUnit.ParentPercentage)
marker.Depth = New NLength(4, NRelativeUnit.ParentPercentage)
marker.AutoDepth = False
marker.PointShape = PointShape.Sphere
line.MarkerStyles(0) = marker

line.XValues.Add(x1)
line.Values.Add(y1)
line.ZValues.Add(z1)

line.XValues.Add(x2)
line.Values.Add(y2)
line.ZValues.Add(z2)
End Sub

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

Dim chart As NChart = NChartControl1.Charts(0)
Dim line As NLineSeries = CType(chart.Series(0), NLineSeries)

Dim ring As New NLineSeries
chart.Series.Add(ring)
ring.DataLabelStyle.Visible = False
ring.MarkerStyle.Visible = False
ring.Legend.Mode = SeriesLegendMode.None
ring.InflateMargins = False
ring.BorderStyle = New NStrokeStyle(New NLength(1), Color.Blue)
ring.UseXValues = True
ring.UseZValues = True

Dim pointCount As Integer = 25
Dim segmentCount = pointCount - 1
Dim angleStep As Double = (2 * Math.PI) / segmentCount

' calculate unit vector
Dim xA As Double = line.XValues(0)
Dim yA As Double = line.Values(0)
Dim zA As Double = line.ZValues(0)

Dim xN As Double = line.XValues(1) - xA
Dim yN As Double = line.Values(1) - yA
Dim zN As Double = line.ZValues(1) - zA

Dim length As Double = Math.Sqrt(xN * xN + yN * yN + zN * zN)
xN = xN / length
yN = yN / length
zN = zN / length

Dim dist As Double = rand.NextDouble() * length
Dim radius As Double = 2.6

Dim cosB As Double = Math.Sqrt(xN * xN + zN * zN)
Dim sinB As Double = yN

Dim gamma As Double = Math.Atan2(zN, xN)
Dim cosG As Double = Math.Cos(gamma)
Dim sinG As Double = Math.Sin(gamma)

For i = 0 To pointCount - 1 Step 1

Dim alpha As Double = i * angleStep
Dim x As Double = 0
Dim y As Double = Radius * Math.Sin(alpha)
Dim z As Double = Radius * Math.Cos(alpha)

Dim x1 As Double = cosB * x - sinB * y
Dim y1 As Double = sinB * x + cosB * y
Dim z1 As Double = z

Dim x2 As Double = cosG * x1 - sinG * z1
Dim y2 As Double = y1
Dim z2 As Double = sinG * x1 + cosG * z1

ring.XValues.Add(xA + xN * dist + x2)
ring.Values.Add(yA + yN * dist + y2)
ring.ZValues.Add(zA + zN * dist + z2)

Next i

NChartControl1.Refresh()

End Sub

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

Dim x1 As Double = rand.NextDouble() * 40
Dim y1 As Double = rand.NextDouble() * 40
Dim z1 As Double = rand.NextDouble() * 40

Dim x2 As Double = rand.NextDouble() * 40
Dim y2 As Double = rand.NextDouble() * 40
Dim z2 As Double = rand.NextDouble() * 40

CreateBaseLine(x1, y1, z1, x2, y2, z2)

NChartControl1.Refresh()
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
NChartControl1.ShowEditor()
End Sub
End Class


Attachments
BruceGuthrie.zip (41 views, 15.00 KB)
Bruce Guthrie
Posted 14 Years Ago
View Quick Profile
Junior Member

Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)Junior Member (14 reputation)

Group: Forum Members
Last Active: 6 Years Ago
Posts: 14, Visits: 2

Hello Milen

 

thanks for the code that is exactly what i wanted to do and more. let me try this out on my projetcs and see what i can acheive.

 

Regards

Bruce.





Similar Topics


Reading This Topic