Draw circle perpendicular to a line...

Hi,

I want to programatically draw a circle, at a given point along a line (or spline), so that the circle is perpendicular to the line at that point.

 

So, almost like extruding a shape along a linear element, where the shape (a planar shape) has to be placed perpendicular to the linear element.

 

Been looking what methods are available, but cant find one that makes any sense.

BTW - doing this in C# .net, so been looking at the VBA help.

Thanks!

Parents
  • Math basics or misunderstanding ?

    Each tangent of a circle is perpendicular to it's radius. There is no other given thing for a circle.

    So if your center(point) is outside the line, each circle that has a radius of the minimum distance between the center and the line is perpendicular (or almost not, because there are countless other tangents :) ).

    It might be a good idea to draw an example of what you mean.



  • Hi Michael,

    Misunderstanding i think. Sorry i didnt post a picture - an isometric view below:

    The blue line is the target line, in this case, simply a vertical line. The circle is now dead centre on the line, and it's radii are

    perpendicular to the line, at the insertion point. I know there is a term for the perpendicular vector, but it has escaped me.

     

    So, what i want is, for whatever modification i make to the blue line (move its start/end points), i want that circle to remain fixed as it is currently to the line.

     

     

     

Reply
  • Hi Michael,

    Misunderstanding i think. Sorry i didnt post a picture - an isometric view below:

    The blue line is the target line, in this case, simply a vertical line. The circle is now dead centre on the line, and it's radii are

    perpendicular to the line, at the insertion point. I know there is a term for the perpendicular vector, but it has escaped me.

     

    So, what i want is, for whatever modification i make to the blue line (move its start/end points), i want that circle to remain fixed as it is currently to the line.

     

     

     

Children
  • Someone who's working in 3D :-)

    OK, that makes it clearer. I currently have some code in mdl on my computer in the company that aligns a normal (from polygon or similar) with a line. This should work here even.

    I'll be back on Monday, but you might need someone else for the C# part :)

    Michael



  • PlanarElement Interface

    The PlanarElement interface provides what you want. A circle is a closed element that supports that interface. PlanarElement.Normal yields a normal vector as a Point3d. Use methods that act on Point3d data to create a set of vertices, then create your LineElement from those vertices.

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • John, if I understand your needs, you want to create that circle and not that line, so it think you want to look into example about frenet frame.

    Dan

  • Hi Dan, yep, thats exactly what i want to do. Im not too worried about the line, its just the circle or planar element.

    Frenet frame? MS example or should i google it?

  • Thanks Jon, I will take a look at PlanarElement, see if that offers any solutions.

  • johnds said:

    Hi Dan, yep, thats exactly what i want to do. Im not too worried about the line, its just the circle or planar element.

    Frenet frame? MS example or should i google it?

     

    You have a lucky day, I have found one of my examples from time when I wanted to be a MVBA teacher...

    I modified it little bit to create perp. circles around all traversable elements in selection...

    Select any linear elements, call CirclesAlongSelection and you will see what will happen.

    If you will need some help with converting from VBA to C#, ask it here...

    If you would want to avoid using of BSplines, let's say... There is another option to get frame. We can calculate it from tangent vector...

     

    Sub CirclesAlongSelection()

        Dim sel As ElementEnumerator
        Dim norm As Point3d
        Dim bspl As BsplineCurve
        Dim dst As Double, length As Double
        
        ' get selected elements into enumerator
        Set sel = ActiveModelReference.GetSelectedElements
        
        ' world's normal
        norm = Point3dFromXYZ(001)
        
        ' while any element in selection
        While sel.MoveNext
          ' only if it is convertable to BSpline
          If sel.Current.IsTraversableElement Then
            ' convert it to BSpline curve
            Set bspl = New BsplineCurve
            bspl.FromElement sel.Current
            
            ' compute length of curve
            length = bspl.ComputeCurveLength()
            
            ' place perpendicular cirlces along element
            ' step is 1 unit, radius is 3 units
            For dst = 0 To length Step 1
                Call DrawCircleAtDistance(bspl, 3, dst, norm)
            Next dst
            
          End If
        Wend
        
    End Sub

    Sub DrawCircleAtDistance(bspl As BsplineCurve, radius As Double, _
                             distance As Double, lNorm As Point3d)

        Dim pnt As Point3d
        Dim ff As Matrix3d
        Dim param As Double, curv As Double, tors As Double
        Dim ell As EllipseElement
        Dim ellPts(2As Point3d
        
        ' get point at distance and its parameter
        pnt = bspl.EvaluatePointAtDistance(param, distance)
        
        ' evaluate frenet frame at parameter
        ' frenetFrame stores in its rows the tangent (RowX),
        ' main normal (RowY) and binormal (RowZ) of the curve
        ' at the given parameter
        bspl.EvaluatePointFrame ff, curv, tors, param, lNorm
         
        ' calculate points of circle
        ellPts(0) = Point3dAddScaled(pnt, ff.RowY, radius)
        ellPts(1) = Point3dAddScaled(pnt, ff.RowZ, -radius)
        ellPts(2) = Point3dAddScaled(pnt, ff.RowY, -radius)
        
        ' create circle
        Set ell = CreateEllipseElement1(Nothing, ellPts(0), ellPts(1), ellPts(2))
         
        ' if circle is valid element, add it to design file
        If (Not ell Is NothingThen
            ActiveModelReference.AddElement ell
        End If

    End Sub
  • perfect Dan :)

    I would have went the other way, creating the circle and align it's normal with the given line. But that's because I have some routines to do so :)

    Your code will enable him to use it for more than lines and it should be fast enough, although the bspline calculation is somewhat overkill if he really only has lines.



  • Thanks :-)...

    In MDL it is also possible to use mdlElmdscr_pointAtDistance to get point and tangent. Then, we have a 2d world normal and tangent, so we can, using crossproduct, calculate normal. And if we have a normal and tangent, another crossproduct will give us binormal, so BSplines and frenet frame is not needed, but it was a nice example for MVBA training...

    Dan

  • Hi guys,

    Dan, your example was great, but unfortunately EvaluatePointFrame is only available on BSplines.

    I need to do the same thing on lines, circles, elipses, shapes, etc. And I need 3D coordinates.

    So, how would I, for example, draw that circles on, say, an ellipse, just like what you did using FrenetFrame on the spline?

  • John, have you tried to run that example on selection with ANY LINEAR ELEMENTS ( lines, circles, ellipses, shapes, etc. )?

    I can say, YOU HAVE NOT!!!

    That example perfectly works on any of element types you listed.

    If you look more close into that example, you will find that it handles all elements convertable to BSpline, not only BSplineElements.

    The logic is:

    1. Get any traversable (line, circle, ellipse, shape, etc.) element
    2. Convert it to BSplineCurve
    3. Get point on curve
    4. Get parameter for this point
    5. Get frenet frame for this parameter
    6. Calculate points of circle
    7. Draw circle

    Dan