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.

     

     

     

  • 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

  • Hi Dan,

    Nope, i did not try using your sample on elements other than Bspline. I was not aware that you could convert other types to Bspline.

    So, what I did also was try to see if the other types had the same method on them, which they did'nt. Strange why MS did not provide such a method on the other types, rather than having to use the technique you showed in your example.

    I mean, will an ellipse or a shape, converted to a BSpline, give the same thing as the original??

    interesting.

    John.

  • From my vault, I just assembled this routine...

    Is roughly what you are looking for?

    Regards, Marcos

    CirclePerp.ma
  • B-Splines: everyman's curve

    Unknown said:
    Strange why MS did not provide such a method on the other types, rather than having to use the technique you showed in your example.

    Are you suggesting that a family of functions mdlLine_doSomething, mdlEllipse_doSomething, mdlShape_doSomething, mdlComplexShape_doSomething, etc. would be more digestible than mdlBSpline_doSomething? No — it's easier to convert everything to a super-curve that provides the geometric capability of each type of element plus the ability to be manipulated easily. To put it another way, B-Splines provide an elegant solution to complex problems.

    Unknown said:
    I mean, will an ellipse or a shape, converted to a BSpline, give the same thing as the original?

    One way is to try it, which you can do quite easily in MicroStation without writing any code.

    It's a bit like asking "If I treat a circle as an ellipse, can I be sure that it works the same?" Yes, because a circle is just a special case of an ellipse. Similarly, a B-Spline is a generalisation of the concept of a curve (where a straight line is just a special case of a curve). The only way you can be absolutely convinced is to learn the mathematics of B-Splines.

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Unknown said:
    Are you suggesting that a family of functions mdlLine_doSomething, mdlEllipse_doSomething, mdlShape_doSomething, mdlComplexShape_doSomething, etc. would be more digestible than mdlBSpline_doSomething?

    Yes Jon, why not? Just like PointAtDistance is available to most of the element types because of some super-interface, why not EvaluatePointFrame?

    I think it is ridiculous to have some other type (BSpline for instance) try to do the work that should be handled by the actual types that should provide their own implementation of how to evaluate a point frame. So now, BSpline type has lots of extra baggage to convert all the other types to a spline, just so that one method would not be spread across all those other types?

    Comon, Jon, an Ellipse is definitely not a spline, and the closest spline to fit the curvature of an ellipse would probably contain thousands of poles/control points (well, at least that's what happens in AutoCAD, and I'm not a fan of acad.)

     

    But anyway, I will take your advice and see how Microstation does the conversion/approximation, I dont know, maybe it does a spot on job. Thanks for the tip.

  • John,

    I'm confused. Did you get an answer to your original question?

    If not then look at mdlProject_perpendicular. Given a pick point on an element descriptor, it will return a point on the element, the tangent at that point and a perpendicular at that point. I've never needed anything but NULL for inputRotMatrix but I usually work in 2D. The docs don't say but I'd guess that just defaults to the view rotation matrix. The pseudocode I'd try is:

    1. mdlProject_perpendicular(&pointOn,&tangent,&perpen0,...);
    2. mdlVec_normalize(&tangent) ;// just to be sure
    3. mdlVec_normalize(&perpen0);
    4. mdlVec_crossProduct(&perpen1,&tangent,&perpen0); //get a vec -90 degrees from perpen but still perpendicular to element
    5. mdlVec_crossProduct(&perpen2,&perpen0,&tangent); //get a vec 90 degrees from perpen but still perpendicular to element
    6. mdlVec_scaleInPlace(&perpen0,radius);
    7. mdlVec_scaleInPlace(&perpen1,radius);
    8. mdlVec_scaleInPlace(&perpen2,radius);
    9. mdlCircle_createBy3Pts(&perpen1,&perpen0,&perpen2);

    There are other ways to create a circle with the pointOn, tangent and perpendicular and there may be a currtrans step or two I've left out but you get the idea.

    Regards,

    Charles Griffith

  • Charles -- a good suggestion, but unfortunately this is really a VBA question posted in the wrong Forum.

     
    Regards, Jon Summers
    LA Solutions

Reply Children
  • Unknown said:
    This is really a VBA question

    I wouldn't think the implementation language is an issue since each function mentioned has a documented VBA Wrapper Declaration and the initial question relates to C#. The key is to use mdlProject_perpendicular to get the principal parameters to build a planar element (a circle or anything else) perpendicular to the path element. This approach can be generalized to any path element available in MicroStation. A little effort with this function along with most of what Dan has suggested should yield the desired result without the need to convert the path to B-spline.

    For curvi-linear paths, B-spline is a nice approximation but it would not be my choice for conic sections (ellipse, parabola, etc.) or for shapes that may contain discontinuities in the path first derivative (square and other polygons). If b-spline representations of conic sections were as good as your circle example suggests, then why are there so many scholarly papers on the subject of "b-spline approximation to conic curves"? The answer is that while the approximation may fool the eye, it is still an approximation and the error bounds can prove unacceptable in many application domains. 

  • Unknown said:

    I wouldn't think the implementation language is an issue since each function mentioned has a documented VBA Wrapper Declaration and the initial question relates to C#. The key is to use mdlProject_perpendicular to get the principal parameters to build a planar element (a circle or anything else) perpendicular to the path element. This approach can be generalized to any path element available in MicroStation. A little effort with this function along with most of what Dan has suggested should yield the desired result without the need to convert the path to B-spline.

    For curvi-linear paths, B-spline is a nice approximation but it would not be my choice for conic sections (ellipse, parabola, etc.) or for shapes that may contain discontinuities in the path first derivative (square and other polygons). If b-spline representations of conic sections were as good as your circle example suggests, then why are there so many scholarly papers on the subject of "b-spline approximation to conic curves"? The answer is that while the approximation may fool the eye, it is still an approximation and the error bounds can prove unacceptable in many application domains. 

     

    Charles, you suggested MDL function mdlProject_perpendicular, but BSpline approximation is not good for you. I just want to inform you, that method you suggested uses approximation as well and I do not think that more accurate. Look at its last argument. It is inputTolerance, this suggests, that before any evaluation of perpendicular point is made, input element is approximated. It is stroked by this tolerance, so it also may be (on ellipses for example) less accurate than BSPline approximation...

     

    Dan

  • Dan, Charles

    You both have been very helpfull, and clearly both have strong, if not slightly differing opinions on the matter of bspline conversion of other types and its appoximation.

    I wonder if somebody from Bentley would actually be able to shed some light on which method would actually yeild the most accurate result, and under what conditions/tolerances?

    John

  • John, there is nothing to get from Bentley, it is basic math. I understand, what Charles means and how does he mean it, but difference between MicroStation and some another CADs is that it has really accurate methods of BSpline approximation. Let's get for example conversion of polygon/linestring to BSpline. Polygon/linestring is nothing more than BSpline of 2nd order. Another thing is that MicroStation supports many BSpline curve types and also BSpline chains, so converter may select the best for conversion.

    For your solution, you have to decide which method you will use.

    You have two options:

    1. BSpline approximation
    2. Polygon/LineString approximation

    Both are accurate enough and have almost same results...

    In my program I use them both. If Input element is elliptical (arc, circle, ellipse, part of ellipse) or curve, I use BSpline approximation. While if input element is Linear (line, linestring, shape) I use Polygon/LineString approximation. If element is complex, I drop it first to simple parts...

    Dan

  • Hi --I'm not a good resource for what's available through what API and developer environment, but the following may be helpful

    The short summary of what I write below is:  bsplines form of line/linestring/circle/ellipse are exact.  Points and tangents "on" the bsplien are as accurate as points and tangents of ellipse or line.    There is only one fussy are of round-tripping through "distance from start" may be less than machine precision in the circle/ellipse case.

    • The bspline image of a line, linestring, ellipse, or circle is not an approximatioin
      • Every xyz "on" the primary is exaclty "on" the bspline
      • Every xyz "on" the bspline is exactly "on" the primary
      • There are no gaps (i.e nothing like the gap from a linestring to a curve that it samples)
    • When you get a "point and tangent" from a bspline they are exact (to machine precision)
      • (i.e. nothing worse than the usual bit loss in floating point calculations
      • Data close to the origin is good and wholseome
      • If you data is "on Pluto" you are asking for trouble in ALL calculations  -- sort fo like pushing your car to 5000 RPM just to see what happens.
    • When you project a space point to a bspline, the useful result is the "parameter" along the bspline.  0 is start, 1 is end, and fractional parameters move forward. 
      • Converting the fraction to a point (and tangent) is exact to machine precision.
    • One issue where there may be less than machine precision is use of "distance along" as a way saying where you want your circle center.
      • "Distance along" to point conversions are closed forms ONLY for LINE, LINESTRING, and TRUE CIRCLE, and LINEAR BSPLINE.
      • They are not exact for ELLIPSE or BSPLINE OTHER THAN LINEAR.
      •  A round trip of "distance along" to "point" and back to "distance along" may have some errors ,  How bad?   maybe 8 to 12 digits out.
      • Compared to 10 or 15 years ago, Microstation is much more aggressive than it used to be about pushing that towards full precision.