Skip to content

Update README.md #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

Akiraa3374
Copy link

"""Grasshopper Script Instance"""
import sys as sys
import Rhino
import Grasshopper

import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import random as r

I would like to make some flowers.

#############################################

0. Making a pot

#############################################

plane1 = rs.WorldXYPlane()
circle1 = rs.AddCircle(plane1, 0.2)

plane2 = rs.MovePlane(rs.WorldXYPlane(), [0,0,0.6])
circle2 = rs.AddCircle(plane2, 0.25)

plane3 = plane2
circle3 = rs.AddCircle(plane3, 0.2)

plane4 = rs.MovePlane(rs.WorldXYPlane(), [0,0,0.5])
circle4 = rs.AddCircle(plane4, 0.19)

loft_this = [circle1, circle2, circle3, circle4]

pot = rs.AddLoftSrf(loft_this, start=[0,0,0],
end=[0,0,0.5], loft_type=2)

earth = rs.AddPlanarSrf(circle4)

#############################################

1. Creating the seeds

#############################################

We have to plant seeds inside the pot.

Unfortunately not all seeds will flourish,

if they are planted at too close a distance.

number_of_flowers = 10

seeds = []

for i in range(number_of_flowers):

# Generate random (u, v) parameters
    
u = r.random()
v = r.random()
    
# Evaluate the surface at (u, v) to get the 3D point
    
point = rs.EvaluateSurface(earth, u, v)
    
seeds.append(point)

#############################################

2. Create the positions for the flowerheads

#############################################

Moving them in z-direction...

...and pushing the flowerhead positions outwards.

flower_height = 0.5

flowerheads = seeds

centroid = (rs.SurfaceAreaCentroid(earth)[0][0],
rs.SurfaceAreaCentroid(earth)[0][1],
flower_height)

flowerheads = rs.MoveObjects(flowerheads, [0,0,flower_height])
flowerheads = rs.ScaleObjects(flowerheads, centroid, [3,3,0], False)

#############################################

3. Creating the growth_paths

#############################################

I do this by simply using interpolating curves,....

... which are perfect for this purpose:

Define a starting point and vector and an end point and vector....

.... and you will get a smooth cuve between the points....

.... with the vectors as tangents.

First creating the vetors...

flowerhead_vectors = []

for i,seed in enumerate(seeds):
vector = rs.VectorCreate(seed, flowerheads[i])
flowerhead_vectors.append(vector)

...then the growth_paths.

growth_paths = []

for i,seed in enumerate(seeds):
growth_path = rs.AddInterpCurve(
[seed,flowerheads[i]], degree=3, knotstyle=0,
start_tangent=(0,0,1), end_tangent = flowerhead_vectors[i])
growth_paths.append(growth_path)

Now, for creating the flower straws.

#############################################

4. Creating the flower_operation

#############################################

4.1 Pascals Operation

Pascals Theorem states the following for every ellipse:

If you draw 6 different tangents on the elipse ....

....and take their intersection points...

.... you can create connecting lines between these points.....

.... that will always intersect each other in one point.

Using this theorem allows me to create flowerheads...

....with petals that all converge to one point.

def Pascal_Operation(x,y):

ellipse_id = rs.AddEllipse(rs.WorldXYPlane(), x, y)
    
# Calculate tangent lines .... only as point pairs because thats all we need for now
tangent_lines = []
for i in range(6):  # Divide curve into 6 equal parts to get tangent points
    param = i * rs.CurveLength(ellipse_id) / 6
    point = rs.EvaluateCurve(ellipse_id, param)
    tangent = rs.CurveTangent(ellipse_id, param)
    points_of_tangent_line = [
         point + x * tangent,
         point - x * tangent,
            ]
    tangent_lines.append(points_of_tangent_line)
    
# Calculate intersections of neighboring tangents
intersections_of_tangents = []
for i in range(6):
    tangent_1 = tangent_lines[i]
    tangent_2 = tangent_lines[(i + 3) % 6]


    intersection = rs.LineLineIntersection(
        (tangent_1[0], tangent_1[1]), (tangent_2[0], tangent_2[1])
    )
    if intersection:
        intersections_of_tangents.append(intersection[0])
    
# Calculate intersecting lines (again only as point pairs because thats all we need for now) and...
# ...determine the intersection of just two lines (the third is automatically concurrent with the others).
    
line_0 = intersections_of_tangents[0], intersections_of_tangents[3]
line_1 = intersections_of_tangents[1], intersections_of_tangents[4]

central_intersection = rs.LineLineIntersection(
    (line_0[0], line_0[1]), (line_1[0], line_1[1]))
    
return tangent_lines, intersections_of_tangents, central_intersection

now using this definition of pascals sentence...

... we make some nice flowers.

Its gonna be fun!

4.2 Creating a function for what i like to call "petal_rings"

def petal_ring(x,y, petal_division):

ellipse_id = rs.AddEllipse(rs.WorldXYPlane(), x, y)

rs.CurveSeam(ellipse_id, petal_division)

intersections_of_tangents = Pascal_Operation(x,y)[1]
central_intersection = Pascal_Operation(x,y)[2]

convex_curves = rs.SplitCurve(ellipse_id, [i * 1/6 for i in range(6)])

concave_curves = []

# Creating the upper end of each petal...
# ...by mirroring the ellipse-segments along the ellipse-tangents

for i in range(6):

    start_point = intersections_of_tangents[i]
    end_point = intersections_of_tangents[(i+1) % 6 ]

    concave = rs.MirrorObject(convex_curves[i % 5], start_point, end_point, True)
    concave = rs.MoveObject(concave, [0,0, x * 1.5])
    concave_curves.append(concave)

petals = []

for i in range(6):

    petal = rs.AddLoftSrf([concave_curves[i % 5], convex_curves[i % 5]], 
                        loft_type=1)
    petals.append(petal)

return ellipse_id, petals, central_intersection

4.3 Creating the flowerheads

def blossom(x,y):

step_size = 0.03

# generate the outer ring of petals

outer_ring = petal_ring(x,y, 0)[1]

# generate the inner, offset ring of petals

outer_ring_center = petal_ring(x,y, 0)[2]

x2 = x * 0.75
y2 = y * 0.75

inner_ring = petal_ring(x2,y2, 1/6)[1]

inner_ring_center = petal_ring(x2,y2, 1/6)[2]

# Aligning the inner and the outer ring
direction = rs.VectorAdd(outer_ring_center - inner_ring_center, [0, 0, step_size])
inner_ring = rs.MoveObjects(inner_ring, direction)

# putting both rings together and creating the entire blossom
double_ring = inner_ring | outer_ring

blossom = []

for i in range(6):
    ring = rs.ScaleObjects(double_ring, outer_ring_center, 0.5, copy=True)
    ring = rs.MoveObjects(ring, [0, 0, step_size])
    for i in ring:
        blossom.append(ring)

return blossom, outer_ring_center

#############################################

5. Bringing it all together

#############################################

blossom_positioned = []

for i in range(number_of_flowers):

#Create radii for the ellipses, within a certain boundary...
# ...to create differently shaped flowerheads.

u = r.uniform(0.05, 0.09)
v = r.uniform(0.05, 0.09)

flowerhead = blossom(u,v)

# reorienting the flowerhead

reference = [flowerhead[1], [0,0,1], [0,1,0]]

for i in flowerhead:
    target = [flowerheads[i], flowerhead_vectors[i] + flowerheads[i], 
    rs.VectorCrossProduct(flowerheads[i], flowerhead_vectors[i] + flowerheads[i])]
    flowerhead = rs.OrientObject(flowerhead[0][i], reference, target, flags = 0)

    blossom_positioned.append(flowerhead)

#############################################

6. Visualizing it

#############################################

blossoms = blossom_positioned
pot = pot
earth = earth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant