Parabolic curve y=-x*x

Parabolic curve y=-x*x

Anonymous
Not applicable
25,411 Views
12 Replies
Message 1 of 13

Parabolic curve y=-x*x

Anonymous
Not applicable

How to write a parabolic curve (equation; y=-x^2) in AutoLISP?

Plz help me.

0 Likes
Accepted solutions (1)
25,412 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

Try this.  Call for a "degree" of 2, -1 coefficient on X^2, and the default 0 for the coefficient on X and the constant.

Kent Cooper, AIA
Message 3 of 13

Shneuph
Collaborator
Collaborator

It would be

(expt x 2)

Edit:

 

-x would be 

(expt (* -1 x) 2)
---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 4 of 13

Kent1Cooper
Consultant
Consultant

@Shneuph wrote:

.... 

-x would be 

(expt (* -1 x) 2)

You can make a number negative directly with a (-) function, rather than multiplying it by -1.  That can be just:

 

(expt (- x) 2)

 

But be careful about what you ask for.  That will give you the same result as (expt x 2) [squaring a negative number gives a positive number].  I suspect they're looking instead for this:

 

(- (expt x 2))

 

Another way:

 

(* x (- x))

Kent Cooper, AIA
0 Likes
Message 5 of 13

JamesMaeding
Advisor
Advisor

also note that you can make a parabola in acad natively with a 3 point heavyweight pline, with smoothing.

set splinesegs as needed to get resolution desired.

Civils have done this for a long time to get vertical curves drawn accurately.

snippet of code we use

 

(COND ((<= VCL 500) (SETQ SEGS 100))
            ((<= VCL 1000) (SETQ SEGS 160))
            ((<= VCL 2000) (SETQ SEGS 240))
            ((> VCL 2000) (SETQ SEGS 360))
      )
      (SETVAR "splinetype" 5)
      (SETVAR "splinesegs" SEGS)
  ;DRAW POLYLINE
      (COMMAND "pline" BVC PVI EVC "")
      (COMMAND* "pedit" "l" "s" "")


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 6 of 13

JamesMaeding
Advisor
Advisor

seriously, that needs a login to download, here is the code:

;;  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.")

internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 7 of 13

john.uhden
Mentor
Mentor

Ahem.  All you need to do is to create a 3-point polyline, then PEDIT Spline curve, then in properties, change its Fit/Curve to quadratic.

 

I'm sure it can be done programatically, but I will leave that up to you wizards.  Just do an entget or a dump.

 

BTW, it will remain a 3-point polyline, just a little heavier.  C'mon, James, you've seen them in Land Desktop a million times; that's how they drew vertical curves, parabolas you know?  I still can't figure out the guy from Egypt or wherever who claimed his vertical curves were arcs.  Maybe they were visited by a different strain of alien ancestors.  The closest thing we have to a pyramid is a salt dome (which you guys down south may not have).  Anyway, they are using magnesium chloride more these days, as a liquid.

John F. Uhden

0 Likes
Message 8 of 13

JamesMaeding
Advisor
Advisor

@john.uhden

Yep, that is what my code does 2 posts back.

The big old lisp thing one post back was someone elses code that I never have used.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 9 of 13

john.uhden
Mentor
Mentor

Oh yeah.  Put the blame on someone else, eh?

 

Yes, you do deserve credit for a few posts back.  I'll attend to that.  You're a good guy, James.  I usually tease only those whom I like.

John F. Uhden

Message 10 of 13

JamesMaeding
Advisor
Advisor

@john.uhden

for sure, just wanted you to know I did not throw up that huge set of code when a couple lines would do it.

So few civils know a polyline with quadratic smooth is exactly the same shape as a vertical curve!


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 11 of 13

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

seriously, that needs a login to download, here is the code: 


No, it doesn't.  You never need to log in to download files on the CAD Tips site.  You do if you want to comment on one, and some other tid-bits, but anyone can download Tips -- see the first sentence under Register on the main CAD Tips page -- if not logged in, you are the "guest" they refer to.

Kent Cooper, AIA
0 Likes
Message 12 of 13

wkmvrij
Advocate
Advocate

Very interesting reading as well : http://www.digitalcad.com/2001/05_may/features/math1.htm. There is a link in it to a LSP file that will plot curves too.

Message 13 of 13

JamesMaeding
Advisor
Advisor

I see now, chrome was somehow hiding the download, even when I picked.

So I switched to IE which is how I normally log into cadalyst and it dis but then chrome finally showed the download, odd.

 

Anyway, I like Cadalys for Robert Green's articles. Poor Lynn Allen's videos have become hokey. I still think she does top notch training composition, just wish it was a little more serious like she was years ago.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes