Create Grasshopper Component from AutoCAD LISP Routine

Given AutoCAD LISP Routine to generate a parabolic curve thru 3 points in the x-y plane with n segments of equal values of x dimensions along x axis → Create a Grasshopper component to accept given x-y plane, 3 points, and n number of segment of equal x values …generate a parabolic curve y=ax2+bx+c with the given number of segments n.

The AutoCAD LISP routine is written below. Please help me out here … Thank You,

pedro

(defun C:par( / pt1 pt2 pt3 pt_a pt_b dx x y x_start x_end num_pts a b c
ret_list ocmd oblip sset ent1)

(setq ocmd (getvar "cmdecho") oblip (getvar "blipmode"))
(setvar "cmdecho" 0)
(setvar "blipmode" 0)

(initget 7)
(setq pt1 (getpoint "\nSelect first point on parabola:"))
(setq pt2 (getpoint "\nSelect second point on parabola:"))
(setq pt3 (getpoint "\nSelect third point on parabola:"))

(setq num_pts (getint "\nNumber of points to use:"))

(setq ret_list (get_coeff pt1 pt2 pt3))

(setq a (nth 0 ret_list)
b (nth 1 ret_list)
c (nth 2 ret_list)
x_start (nth 3 ret_list)
x_end (nth 4 ret_list)
)

(setq dx (/ (- x_end x_start) (float num_pts) ))

(setq x x_start)
(setq y (fpoly a b c x))
(setq pt_a (list x y 0.0))
(setq x (+ x_start dx))

(setq sset(ssadd))

(repeat num_pts
(setq y (fpoly a b c x))
(setq pt_b (list x y 0.0))
(command "_.pline" pt_a pt_b "")
(command "_.point" pt_a pt_b "")
(setq sset (ssadd (entlast) sset))
(setq pt_a pt_b x (+ x dx) )
)

(command "_.point" pt_a pt_b "")

(command "_.pedit" "L" "J" sset "" "")

(setvar "cmdecho" ocmd)
(setvar "blipmode" oblip)

)

(defun get_coeff(pt1 pt2 pt3 / x1 x2 y1 y2 x3 y3 x1sq x2sq x3sq
a b c ret_list)

(setq x1 (car pt1) y1 (cadr pt1) x1sq (* x1 x1) )
(setq x2 (car pt2) y2 (cadr pt2) x2sq (* x2 x2) )
(setq x3 (car pt3) y3 (cadr pt3) x3sq (* x3 x3) )

(setq x_start (min x1 x2 x3) x_end (max x1 x2 x3))

(setq det1 (det x1sq x2sq x3sq x1 x2 x3 1.0 1.0 1.0))

(setq a(/ (det y1 y2 y3 x1 x2 x3 1.0 1.0 1.0) det1))
(setq b(/ (det x1sq x2sq x3sq y1 y2 y3 1.0 1.0 1.0) det1))
(setq c(/ (det x1sq x2sq x3sq x1 x2 x3 y1 y2 y3 ) det1))

(setq ret_list (list a b c x_start x_end))

)

(defun fpoly(a b c x / y)

(setq y (+ (* a x x) (* b x) c) )
)

(defun det(a1 a2 a3 b1 b2 b3 c1 c2 c3 / ret_val)

(setq ret_val (+
(* a1 (- (* b2 c3) (* b3 c2) ))
(* b1 (- (* c2 a3) (* c3 a2) ))
(* c1 (- (* a2 b3) (* a3 b2) ))
)
)
)

Hi @Pedro_R_Munoz,

RhinoCommon exposes two functions to create parabolic-sharped NURBS curves:

NurbsCurve.CreateParabolaFromFocus

and

NurbsCurve.CreateParabolaFromVertex

With either a C# or Python component, you can use these.

— Dale

Hi @dale thank you for the two leads … more specifically I am looking for a way to generate a grasshopper component similar to the LISP routine to create a segmental parabola curve thru any 3 points and of n number of segments having the same x coordinates of equal distance between consecutive points and the start and end points that may not necessarily be the vertex and the start or end points … hopefully someone may have some quick method to convert from the listed LISP routine to a GH component using any script language such Phyton or any other similar … the AutoCAD LISP routine attached works nicely in AutoCAD but need one GRASSHOPPER component for Rhino … Thank You for your feedback … !!!

Hi @Pedro_R_Munoz,

I can see that the LISP routine interpolates a polyline through points computed with the the parabola equation. There is no reason to do this, as you can create conics with NURBS.

See if this sample helps.

Parabola.gh (6.2 KB)

Also, Rhino has a Parabola command - you might give it a try.

– Dale

Hi @dale the Parabola command from Rhino does not serve my purpose of generating a parabolic (quadratic - y=ax2+bx+c) curve thru any 3 point along the parabola and with n number of segments of equal x-spacing dimension between end points … I did try it but it only works for specific cases of vertex and 2 end points.

let me take a look of your Parabola.gh component to see how it works … Thank You for your feedback … will keep you posted … Also will look at the Parabola3pt from Rhino … I would assume that is in Rhino6, right ??? … will check it out … Thank You !!!

I did find an old Python script for Rhino that I got from Rhino team years ago, let me dust it out and post it to see if this make sense … later we can see how to put it into Grasshopper … Thank You , getting there … I do appreciate your help … !!! Thank You !!!

Hi @dale , here is a Python script to generate Parabola thru 3 points that I got years ago from Rhino Tech support, it works exactly the way I was looking for … so this will be a good candidate to create a GRASSHOPPER COMPONENT, below the script code:

import rhinoscriptsyntax as rs

def fpoly(a, b, c, x):
    y = (a*x*x)+(b*x)+c
    return y;

def det(a1, a2, a3, b1, b2, b3, c1, c2, c3):
    ret_val = (a1*((b2*c3)-(b3*c2)))+(b1*((c2*a3)-(c3*a2)))+(c1*((a2*b3)-(a3*b2)))
    return ret_val;

def get_coeff(pt1, pt2, pt3):
    x1 = pt1[0]
    y1 = pt1[1]
    x1sq = x1*x1

    x2 = pt2[0]
    y2 = pt2[1]
    x2sq = x2*x2

    x3 = pt3[0]
    y3 = pt3[1]
    x3sq = x3*x3
    
    x_start = min(x1, x2, x3)
    x_end = max(x1, x2, x3)

    det1 = det(x1sq, x2sq, x3sq, x1, x2, x3, 1.0, 1.0, 1.0)
    a = det(y1, y2, y3, x1, x2, x3, 1.0, 1.0, 1.0)/det1
    b = det(x1sq, x2sq, x3sq, y1, y2, y3, 1.0, 1.0, 1.0)/det1
    c = det(x1sq, x2sq, x3sq, x1, x2, x3, y1, y2, y3)/det1

    return (a, b, c, x_start, x_end);

#start of main routine
def par():
    pt1 = rs.GetPoint("Select first point on parabola:")
    pt2 = rs.GetPoint("Select second point on parabola:", pt1)
    pt3 = rs.GetPoint("Select third point on parabola:", pt1)

    num_pts = rs.GetInteger("Number of Segments to use:")

    ret_list = get_coeff(pt1, pt2, pt3)

    a = ret_list[0]
    b = ret_list[1]
    c = ret_list[2]
    x_start = ret_list[3]
    x_end = ret_list[4]

    dx = (x_end - x_start)/num_pts
    x = x_start
    y = fpoly(a,b,c,x)
    pt_a = [x, y, 0.0]
    x= x_start + dx

    for i in xrange(num_pts):
        y = fpoly(a,b,c,x)
        pt_b = [x, y, 0.0]
        rs.AddLine(pt_a, pt_b)
        rs.AddPoint(pt_a)
        rs.AddPoint(pt_b)
        pt_a = pt_b
        x=x+dx

# Check to see if this file is being executed as the "Main" python
# script instead of being used as a module by some other python script
# This allows us to use the module which ever way we want.
if __name__ == '__main__':
    par()

Hi @Pedro_R_Munoz,

Again, this code creates a polyline, not a parabola. I guess if you specify enough points, then the polyline might begin to look like a parabola. But in the end, it will still be a polyline.

If you want a real parabola, you’ll need something else.

I’ve attached another sample that creates a NURBS parabola through 3 points. Give it a try and let me know what you think.

ParabolaFromPoints.gh (7.1 KB)

– Dale

Hi @dale , yes certainly the objective is to have a way to create a segmental parabolic curve with a selected n number of segments to be able to discretisize the type of parabolic curve in a number of predefined segments … this with the objective to be able to build real type of structural frameworks with defined segmental parabolic type of profile … will take a look of your grasshopper component to see how it works … getting there … Thank You for your quick feedback … greatly appreciated … !!!

Hi @Pedro_R_Munoz,

Here is your script buried in a Python component.

TestPetro.gh (6.1 KB)

– Dale

RH-74161 is fixed in the latest WIP

Hi @dale @brian i was having trouble with my Python script to handle creating the segmental parabolic curves at different planes of just the x-y plane … managed to get it to work by selecting the right start, end, and intermediate points along the curve depending on the orientation of the parabola branch from the vertex … will take a look of your Grasshopper component to see how it works … Getting There … Thank You so much for your feedback … I am sure this Parabola Thru 3 points Python script may be useful for fans of the Candela Parabolic Groined Vaulted Frameworks to generate doubly ruled anticlastic 3D surfaces … Thank You so much … will test the GH component and see how it works … Thank You !!!

Hi @Pedro_R_Munoz,

I’ve ported your Python code to Grasshopper - see the TestPetro.gh file I posted above (my apologies) for the misspelling.

Your orignal Python code only works in the World xy plane. I did not change this.

The GH file I posted earlier - ParabolaFromPoints.gh - shows how to get around the 2d limitation. You’ll need to modify your code to determine the plane on which the tree points lie. Then transform those points from that plane to the World xy plane, perform your calculation, and then transform the results back to the original plane. Again, this code demonstrates how to do this.

– Dale

sounds great @dale … no worries … will modify the Python code to be able to run the segmental parabola script in any x-y-z plane combination … will upload updated script later … Thank You for the latest GH components … will take a look … it may be tricky and will have to tweak here and there but will make it work in Rhino first to see how it works … Thank You so much … !!!

parabolaHalf3Pts.py (2.3 KB)
parabolaWhole3Pts.py (2.2 KB)

Hi @dale attached are two Python scripts to generate Half and Whole parabolic segmental curves with a number of given n segments along the parabolic curve, being:
Point 1 = Origin - Start end of Parabolic Curve - Start X1 coordinate
Point 2 = End of Parabolic Curve - End X2 coordinate - Line along Point 1 and Point 2 defines the Local X axis of the plane where the parabolic curve is to be generated.
Point 3 = Any point along parabolic Curve

parabolaHalf3Pts.py - generates half branch of a parabolic curve between points 1 and 2, with VERTEX at end point Point 2.

parabolaWhole3Pts.py - generates whole branches up and down of a parabolic curve between points 1 and 2, with Vertex at half distance between points, start Point 1 and end Point 2 …

There is no need to set up any C-plane for the location of the selection points … but the user will have to set up himself the desired lines of the local X-Y axis to be used to generate the parabolic curves …

I tested both scripts for ANY PLANE and they both work fine … Give it a try … it might be confusing at first … but is fun … I will try to upload a Rhino video later when time allows … to show how it works …

finally got this to work … very rudimentary … but it does the work … Thank You to @scottd Scott Davidson as well for his help on the generation of these two python scripts …

Attached is a rhino file depicting the way I use the two python scripts to be able to generate the parabolic curves of the groined vaulted anticlastic 3D framework surfaces of the classical CANDELA groined vaulted domes … the beauty of this is that one is able to create a diagonal grid of intersecting ALL straight lines that will form an anticlastic framework net.
Parabola3Pts-3.3dm (263.1 KB)

1 Like

… and finally be able to generate a “DOUBLY RULED 3D ANTICLASTIC GROINED VAULTED DIAGONAL GRID SURFACE” … as those temporary built TIMBER FORMWORK " done by Master Felix Candela for his remarkable Reinforced Concrete Shells … that now we can then build with “LONG STRAIGHT BAMBOO MEMBERS” .which can be left as PERMANENT FRAMEWORK roof surface for a “SUSTAINABLE” and long lasting timber roof structure … thinking sustainability … and less labor intensive roof fabrication … !!!..

1 Like