Esnap normal to an ellispe

i'm trying to work out reflection angles on an ellipse but esnap doesn't seem to want to snap to it.

is there a trick?
does it not work?
i swear i've done it before.

Comments

  •  Hi Keith,

    doesn't look like _TANGENT & _PERPENDICULAR object snaps are an option with Ellipses in BricsCAD. Perhaps use PELLIPSE to instead draw polyline Ellipses instead in this case?

    Regards,

    Jason Bourhill

    CAD Concepts

  • Hi Keith,

    it is posible and here it is how...!
    Have a look at this Lisp routine over at the "theswamp" :
    http://www.theswamp.org/index.php?topic=12813.msg369597#msg369597
    How it is done it's left to you as homework by studying the routine ( just joking..)
    Here is the code and of cource all credentials and copyright go to the author mentioned in the code
    It's one of the most beatiful routines i have seen

    [code]
    ;;; Draw perpendicular line
    ;;; Alan J. Thompson, 10.15.09
    (defun c:LPer (/ #Ent #Read)
      (and
        (setq #Ent (car (entsel "\nSelect curve: ")))
        (vl-position (cdr (assoc 0 (entget #Ent))) '("LWPOLYLINE" "ARC" "LINE" "CIRCLE" "ELLIPSE"))
        (while (not (eq 25 (car (setq #Read (grread T 15 0)))))
          (princ "\rSpecify point for line: ")
          (redraw)
          (if (vl-consp (cadr #Read))
            (grdraw (vlax-curve-getclosestpointto #Ent (trans (cadr #Read) 1 0) T)
                    (trans (cadr #Read) 1 0)
                    1
            ) ;_ grdraw
          ) ;_ if
          (if (eq 3 (car #Read))
            (entmake (list '(0 . "LINE")
                           (cons 10 (vlax-curve-getclosestpointto #Ent (trans (cadr #Read) 1 0) T))
                           (cons 11 (trans (cadr #Read) 1 0))
                     ) ;_ list
            ) ;_ entmake
          ) ;_ if
        ) ;_ while
      ) ;_ and
      (redraw)
      (princ)
    ) ;_ defun

    [/code]

    Save the code as LPER.lsp
    Load the code from the command line typing (load "lper.lsp")
    Call the program typing the command  Lper
    then...
    Select curve:
    Specify point for line:

    after you draw the perpedicular onto the Ellipse(real ellipse)
    you can easily draw the Tangent and any other conceivable direction...
    Enjoy the dynamic routine (GRREAD is a beautiful function...)

    Here is a screenshot....!!!!



    Best Regards
    Konstantin


  • Keith,

    i forgot to say that you can also use a routine that i developed to draw the so called frenet frame of any curve like ellipse, bspline etc.
    The routine draws a tangent, a normal (perpendicular) and a Bynormal (perpendicular in Z+ direction) lines
    at every Point of a selected curve.
    Please look for details and description in the following thread :

    https://forum.bricsys.com/discussion/18209
    at position #10

    You can call 2 commands :  FrenetF   and  FrenetFP
    : frenetf
    Please select the Curve (can be any curve):
    Please specify Operation ? (Measure-step/Devide-step) :    d
    Please input a STEP (any number < path-length = 131.87 :    15
    : frenetfp
    Select curve:
    select point on curve:

    You find the Lisp Routine attached below

    2D View



    3D Views

      






    FrenetFrameBCAD.lsp

  •  @Konstantin,

    beautiful, thanks for sharing.

    Regards,

    Jason Bourhill

    CAD Concepts


  • There are some issues with the proposed code by Alan J. Thompson:

    1.
    Because the (vlax-curve-getclosestpointto) function is used, sometimes a point on the wrong side of the ellipse is found.

    2.
    During the grread sequence you cannot use normal esnaps. This is problematic for the other endpoint of the line.
  •  Awesome, I run into this issue at least once a week - I think BricsCAD should implement something like this into their entity snaps...
  • I use this. 
    [code]
    (defun c:perpl (/ from_object from_point first_derivative line_angle loop perp_line grread_result end_point str)
      (setvar "CMDECHO" 0)
      (setq old_osmode (getvar "osmode"))
      (if (and (setq from_object (entsel "\nSelect curve at point to start the perpendicular line."))
                                                                         ; select
               (setvar "osmode" 0)
               (setq from_point (cadr from_object))                      ; get the point part
               (setq from_object (car from_object))                      ; get the entity part
               (setq from_point (vlax-curve-getclosestpointto from_object from_point))
                                                                         ; adjust point to be on the entity
               (not (vl-catch-all-error-p
                      (setq first_derivative (vl-catch-all-apply
                                    'vlax-curve-getFirstDeriv
                                      (list from_object (vlax-curve-getParamAtPoint from_object from_point))
                                  )
                      )
                    )
               )                                                         ; get the first derivative
          )
        (progn
          (entmake (list '(0 . "LINE") (cons 10 from_point) (cons 11 from_point)))
                                                                         ; create initial line
          (setq perp_line  (entlast)                                     ; store the initial line
                line_angle  (angle '(0 0 0) first_derivative)            ; get the slope
                loop T                                                   ; loop
          )
    ;      (princ "\nSpecify line length: ")
          (while (and (setq grread_result (grread T 12 0))               ; control cursor, no error on ESC, normal crosshairs
                      (/= (car grread_result) 3)                         ; 3 = point selected
                      loop                                               ; loop is active
                 )
            (cond
              ((= (car grread_result) 5)                                 ; mouse action
                (setq end_point (polar from_point
                                (if (minusp (sin (- (angle from_point (cadr grread_result)) line_angle)))
                                  (- line_angle (/ pi 2))
                                  (+ line_angle (/ pi 2))
                                )
                                (distance from_point (cadr grread_result))
                         )
                )                                                        ; calculate end point
                (entmod (subst (cons 11 (trans end_point 1 0)) (assoc 11 (entget perp_line)) (entget perp_line)))
                                                                         ; modify the line
              )
            )
          )
        )
      )
      (setvar "osmode" old_osmode)
      (princ)
    )
    [/code]


  • another beautiful routine, thanks for sharing Martin.

    Regards,
    Konstantin
This discussion has been closed.