CAD&BIM

Parabola 곡선 그리기

2021. 8. 12. 17:32
반응형

1. 포물선 - 실제 스플라인 포물선 (AutoCAD 용 VLX LISP)

parabola.vlx
0.00MB

 

 

2. lisp 루틴을 사용하여 포물선을 만드는 방법?

 

;;  PolynomialFunction.lsp [command name: PF]
;;  To draw the curve defined by a Polynomial Function in the form Y = a sum of
;;    coefficients on X raised to a descending series of any number of integer powers,
;;    and a constant, e.g. Y = X^4 - 2X^3 + 4.5X^2 - 12X + 17.9
;;  Asks User for whether to draw Spline [uses default start/end tangent directions]
;;    or Polyline of line segments [which can be smoothed with PEDIT Fit], origin to
;;    draw in relation to [X-Y axis intersection], degree [highest exponent applied to
;;    powers of X], coefficient at each degree, constant, bounds in X direction, and
;;    precision [size of increment in X direction between calculated values of Y].
;;  Draws on current Layer, in current Coordinate System.  Places a Point entity at
;;    User's selected origin for reference, if no Point there on current Layer already.
;;  Remembers all choices/options/values, and offers as defaults on subsequent use,
;;    so that function can be run comparatively with [for example] coefficient on just
;;    one power of X changed without needing to re-enter base, other coefficients, etc.
;;  Starts at left bound and proceeds at precision [X increment] intervals.  Note:  If
;;    precision does not divide evenly into overall range of bounds, will stop at last
;;    increment inside bounds, short of right bound by less than one increment.
;;  [Originally included constant as "coefficient" applied to X^0, but if/when X value
;;    is 0, results in (expt 0 0) and "error: function undefined for 0 in negative power."]
;;  Kent Cooper, 10 December 2014

(defun C:PF (/ *error* ev getnum doc svnames svvals n coeffs x); = Polynomial Function

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (prompt (strcat "\nError: " errmsg))
    ); if
    (mapcar 'setvar svnames svvals); reset System Variables
    (vla-endundomark doc)
    (princ)
  ); defun - *error*

  (defun ev (opt); = EValuate what's in global *pf... variable with 'opt' ending
    (eval (read (strcat "*pf" opt)))
  ); defun - ev

  (defun getnum (opt pr f1 f2); = GET NUMerical value for global variable
    ; pr = prompt, f1 = (getreal) or (getint), f2 = (rtos) or (itoa)
    (set (read (strcat "*pf" opt)); makes *pfdeg, *pfcon, or *pfinc
      (cond
        ( (f1 ; = (getint) for *pfdeg, (getreal) for others
            (strcat "\n" pr " <"
              (cond ; default:
                ((ev opt) (f2 (ev opt))); prior value
                ((= opt "inc") "1"); on first use for *pfinc
                ("0"); on first use for others
              ); cond
              ">: "
            ); strcat
          ); f1
        ); User input condition
        ((ev opt)); Enter with prior value
        ((= opt "inc") 1); Enter on first use for *pfinc
        (0); Enter on first use for others
      ); cond
    ); set
  ); defun            

  (defun getbound (which side / boundprev boundtemp)
    ; which = "in" or "ax" for *pfminX or *pfmaxX; side = "left" or "right"
    (setq boundprev (if (ev (strcat "m" which "X")) (rtos (ev (strcat "m" which "X"))) "0"))
      ; default as text [0 if no prior use]
    (while
      (not
        (and
          (not (initget 128)); allow typing value; (not) wrapper to return T
          (setq boundtemp
            (cond
              ( (getpoint
                  (strcat
                    "\nM" which "imum X relative to origin, or pick point for " side " bound <"
                    boundprev
                    ">: "
                  ); strcat
                ); getpoint
              ); picked point or typed value
              (boundprev); Enter
            ); cond & boundtemp
          ); setq
          (or (listp boundtemp) (distof boundtemp)); point or valid numerical typed entry
          (if (= which "ax")
            (> ; then -- right bound is to right of left bound
              (if (listp boundtemp); picked a point
                (car (mapcar '- boundtemp *pfbase)); then -- X relative to origin
                (distof boundtemp); else -- typed value
              ); if
              *pfminX
            ); >
            T ; else [*pfminX]
          ); if
        ); and
      ); not
      (prompt
        (strcat
          "\nRequires numerical typed entry or point"
          (if (= which "ax") " higher than/to right of left bound" "")
          "."
        ); strcat
      ); prompt
    ); while
    (set (read (strcat "*pfm" which "X")); makes *pfminX or *pfmaxX
      (if (listp boundtemp); picked a point
        (car (mapcar '- boundtemp *pfbase)); then -- X relative to origin
        (distof boundtemp); else -- typed value
      ); if
    ); set
  ); defun -- getbound

  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (vla-startundomark doc)
  (setq ; System Variable saving
    svnames '(osmode cmdecho blipmode plinewid)
    svvals (mapcar 'getvar svnames)
  ); setq

  (initget "Spline Pline")
  (setq
    *pfetyp ; global: Polynomial Function Entity TYPe
    (cond
      ( (getkword
          (strcat
            "\nEntity type to draw [Spline/Pline] <"
            (if *pfetyp (substr *pfetyp 1 1) "S"); default [initial letter]: Spline on first use
            ">: "
          ); strcat
        ); getkword
      ); User entry condition
      (*pfetyp); Enter with prior value
      ("Spline"); Enter on first use
    ); cond & *pfetyp
    *pfbase ; global: Polynomial Function BASE point
    (cond
      ( (getpoint
          (strcat
            "\nOrigin base point [X-Y axis intersection for function] <"
            (if *pfbase ; default [in current Units format]: 0,0 on first use
              (strcat (rtos (car *pfbase)) "," (rtos (cadr *pfbase))); then
              (strcat (rtos 0) "," (rtos 0)); else
            ); if
            ">: "
          ); strcat
        ); getpoint
      ); User entry condition
      (*pfbase); Enter with prior value
      ('(0 0)); Enter on first use
    ); cond & *pfbase
  ); setq

  (if (not (ssget *pfbase (list '(0 . "POINT") (cons 8 (getvar 'clayer)))))
    ; not one there already [only one Point for multiple runs with same base]
    (entmake (list '(0 . "POINT") (cons 10 *pfbase)))
  ); if

  (initget 4); no negative
  (getnum "deg" "Degree [highest exponent on X]" getint itoa)

  (repeat (setq n *pfdeg)
    (setq
      coeffs ; list of powers of X paired with coefficients to multiply them by
        ; [local variable: re-build each time, because of possibility of different degree]
      (cons ; add to list
        (cons ; individual exponent paired with its coefficient
          n ; the exponent on X
          (cond
            ( (getreal
                (strcat
                  "\nCoefficient on X"
                  (if (> n 1) (strcat "^" (itoa n)) "")
                  " <"
                  (cond ; default:
                    ((assoc n *pfcoeffs) (rtos (cdr (assoc n *pfcoeffs)) 2 4)); prior value if present
                    ("0"); on first use
                  ); cond
                  ">: "
                ); strcat
              ); getreal
            ); User entry condition
            ((cdr (assoc n *pfcoeffs)))
            (0)
          ); cond
        ); cons
        coeffs
      ); cons & coeffs
    ); setq
    (setq n (1- n))
  ); repeat

  (getnum "con" "Constant" getreal rtos); makes global *pfcon
  (getbound "in" "left")
  (getbound "ax" "right")
  (setq
    *pfcoeffs coeffs ; global: save to offer defaults on subsequent use
    n -1 ; replacing earlier use of variable 'n'
  ); setq
  (initget 6); no 0, no negative
  (getnum "inc" "Precision [increment between X values]" getreal rtos); makes global *pfinc

  (mapcar 'setvar svnames '(0 0 0)); turn off object snap, command echoing, blips
  (if (= *pfetyp "Pline") (setvar 'plinewid 0))
    ; ^-- delete/comment out above line to use whatever current Polyline width is,
    ; or specify standardized width, or prompt User for width
  (command (strcat "_." *pfetyp)); "_.Pline" or "_.Spline"
  (repeat (1+ (fix (/ (- *pfmaxX *pfminX) *pfinc)))
    (command ; feed calculated points out to drawing command
      (list ; build point XY coordinates
        (+ (car *pfbase) (setq x (+ *pfminX (* *pfinc (setq n (1+ n)))))); X coordinate
        (+ ; Y coordinate
          (cadr *pfbase)
          (apply '+ ; add up powers of X multiplied by their coefficients
            (mapcar '(lambda (term) (* (cdr term) (expt x (car term)))) coeffs)
          ); apply
          *pfcon ; constant
        ); + [Y coordinate]
      ); list
    ); command
  ); repeat
  (command ""); finishes command if Polyline, ends point designations if Spline
  (if (= *pfetyp "Spline") (command "" "")); default end tangents finish command
  (mapcar 'setvar svnames svvals); reset
  (vla-endundomark doc)
  (princ)
); defun

(vl-load-com)
(prompt "\nType PF to draw a Polynomial Function.")

 

 

 

반응형

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band