35
$\begingroup$

Foreword

First off, let me say that I am profoundly amazed at the orderliness in nature. If you haven't heard about the Fibonacci sequence (0, 1, 1, 2, 3, 5, 8, 13, ...), you should check it out.

This mathematical concept of the Fibonacci numbers can be shaped into a set of squares, where the lengths of the sides of the squares follow the Fibonacci sequence:

golden ratio

This is sometimes called a golden ratio. It can be formed into a (golden) spiral. (a.k.a. logarithmic spiral):

golden spiral


Application

I am looking for ways on how to utilize this concept in Blender. Primarily in organic modeling. The golden spiral is found all throughout nature. From flower seed heads, sea shells, and ram horns to hurricanes and spiral galaxies. See for yourself. My question is: how can I model based off of one or multiple golden spirals? Specifically, I'm interested in modeling a sunflower head like the one in the following image. I'm mostly interested in the point of origin of the individual seeds (not worried about the shape). Does Blender have any features related to this?

enter image description here

$\endgroup$
4
  • $\begingroup$ It would be good if you could link to a an image of a model that you aim to match - is duplicating smaller objects to make up a larger form acceptable? or are you wanting a continuous surface? $\endgroup$
    – ideasman42
    Commented Jun 25, 2013 at 23:09
  • $\begingroup$ 2d images can convey only limited information about these complex structures and shape-modulations, I recommend to study the physical objects up close too. $\endgroup$
    – zeffii
    Commented Jun 27, 2013 at 11:16
  • 1
    $\begingroup$ Amazing list of interesting answers! $\endgroup$
    – Bithur
    Commented Mar 8, 2015 at 12:04
  • $\begingroup$ hi how was your project on this going? mind if i see your blender file for this project? :) $\endgroup$
    – Ziggy
    Commented Aug 31, 2021 at 12:07

7 Answers 7

36
$\begingroup$

There is a simple mathematical model for florets in a sunflower, using the golden angle 137.5°. Here is an script that creates a mesh with vertices distributed in this pattern:

import bpy
import bmesh
import math

n = 1000 # number of points
c = 0.1 # scale factor

mesh = bpy.data.meshes.new(name="Spiral")
bm = bmesh.new()

for i in range(0, n):
    theta = i * math.radians(137.5)
    r = c * math.sqrt(i)
    bm.verts.new((math.cos(theta) * r, math.sin(theta) * r, 0.0))

bm.to_mesh(mesh)
mesh.update()

from bpy_extras import object_utils
object_utils.object_data_add(bpy.context, mesh)

Note that this pattern does not consist of concentric circles like other answers. It would be interesting if you could generate something like this with existing modifiers or other tools, but I wouldn't know how.

Floret distribution with golden ratio

$\endgroup$
4
  • 1
    $\begingroup$ A few modifications to the technique outline in my answer, results in the same pattern. ;) $\endgroup$
    – Aldrik
    Commented Jun 27, 2013 at 22:36
  • 1
    $\begingroup$ Aha, very nice. $\endgroup$
    – brecht
    Commented Jun 27, 2013 at 22:51
  • $\begingroup$ Stuff like this can be used to create displacement maps too: slightly modified from your code, this attempts to show how the spiral grows over time $\endgroup$
    – zeffii
    Commented Jun 28, 2013 at 8:13
  • $\begingroup$ Note that the angle of 137.5 is very sensitive to change. For a bigger number of points you probably want something like math.radians(137.5077641), otherwise the outer points start to align. $\endgroup$ Commented May 28, 2021 at 12:57
33
$\begingroup$

How about a fully math based approach, here's an interesting paper on scipress.org called Growth in Plants: A Study in Numbers by Jay Kappraff.

from the paper:

Keywords: Phyllotaxis, Fibonacci Numbers, Golden Mean, Continued Fractions, Farey Series, Wythoff’s Game, Zeckendorf Notation

Blender Addon(s)

There is an addon called Add 3d Function Surface which can be coerced into producing many interesting shapes. It is included in the Extra Objects addon as "Math Functions"

enter image description here

If the purely function based approach fails you then you still have a variety of options. Some of which are a bit more interactive.

Modifiers and Scripting

You could model one part of the object and use a script to rotate it around and scale it up/down according to whatever algorithm you can imagine. For example a 2d version of a plant on geometry daily, it's simplicity is deceptive. I tend to use live coding tools like tributary.io to figure out the math using .js with immediate feedback. Usually if I can figure something out in 2D, the move to Blender and adding a third dimension isn't that much extra work.

An Array Modifier and an empty can give very similar results to the broccoli.

enter image description here

This is a cone, tilted slightly and shifted away from its origin, then added an Array modifier and used a tilted (rotated) and slightly scaled empty as an array object.

The fractal nature of the brocolli calls for daisy-chained array modifiers, each building on the complexity of the previous. enter image description here

Elaboration
perhaps a short walk-through script might better convey what otherwise would become a wordy explanation. This script is merely intended to show what daisy-chained Array Modifiers can do, and shouldn't be perceived as nice python or nice code. The script should result in something like the sunflower. Run the code in an empty blend file with the 3D cursor at the centre of the scene.

import bpy
import math
import mathutils
from mathutils import Euler
# make sure 3d cursor is at the center of the scene

num_items_in_spiral = 13
num_spiral_arms = 29
z_rotation = 2.0 * math.pi / num_spiral_arms

# add cone, modify the mesh,
bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.354406, depth=0.901211)
obj = bpy.context.active_object
obj.data.transform(mathutils.Matrix.Translation((-0.5, 0, 0)))

# add empty for spiral arm
bpy.ops.object.empty_add()
obj = bpy.context.active_object
obj.name = "Empty_spiral"
obj.location = (-0.8, 0, 0)
obj.rotation_euler = Euler((0, 0, 0.179609), 'XYZ')

# add empty for radial array
bpy.ops.object.empty_add()
obj = bpy.context.active_object
obj.name = "Empty_radial_array"
obj.rotation_euler = Euler((0, 0, z_rotation), 'XYZ')

# add modifiers to the cone
obj = bpy.data.objects["Cone"]

mod = obj.modifiers.new(name="Array_1", type='ARRAY')
mod.use_relative_offset = False
mod.use_object_offset = True
mod.offset_object = bpy.data.objects["Empty_spiral"]
mod.count = num_items_in_spiral

mod = obj.modifiers.new(name="Array_2", type='ARRAY')
mod.use_relative_offset = False
mod.use_object_offset = True
mod.offset_object = bpy.data.objects["Empty_radial_array"]
mod.count = num_spiral_arms

example image

The red cone is the primary object, the curve/spiral coming off it is the result of one array modifier on a translated and rotated Empty. The rest of the spirals are an extra array modifier on a different Empty (rotated around the scene origin by 2*math.pi / num_spiral_arms)

Whatever object/picture you choose to replicate, you can figure a lot out by drawing on top of the pictures and counting, but mostly experimenting. I think it's more accurate to consider these nice geometric objects as 3D fractals rather than the 3D embodiment of a golden ratio.

$\endgroup$
5
  • 1
    $\begingroup$ I'm inclined to consider the question off-topic as, while it is very interesting and the math can be satisfying, the techniques and information you seem to be looking for are rather generic math / graphics problems. $\endgroup$
    – zeffii
    Commented Jun 25, 2013 at 17:41
  • 2
    $\begingroup$ @zeffi I receive the impression that more questions get closed than upvoted I would strongly disagree to close this one. $\endgroup$
    – stacker
    Commented Jun 25, 2013 at 19:00
  • $\begingroup$ I don't intend to vote for closing it, but it will never be up to one person to close a question unless it is blatantly left field. $\endgroup$
    – zeffii
    Commented Jun 25, 2013 at 19:15
  • 1
    $\begingroup$ @zeffii Could you give more detailed instructions about how you made the tilted cone model? $\endgroup$
    – ajwood
    Commented Jun 26, 2013 at 0:24
  • 1
    $\begingroup$ @ajwood Yes, i'll update this later with a script or two and modify my answer. $\endgroup$
    – zeffii
    Commented Jun 26, 2013 at 4:01
31
$\begingroup$

So many nice answers already. :) I'd like to share my tricky way. too. Steps are shown below:

enter image description here

Demo file is here (UPDATED Jun-30-2024, for Blender 4.x).

$\endgroup$
16
$\begingroup$

Even the human face is based on Phi and Golden Ratio proportions.

Fun stuff, anyway had to have a play:

animated circle

  • Setting up a particle system to spawn the suzanne-flower seeds.
  • Disabled gravity and particle velocity so they'd stay in place.

suzanneflower

$\endgroup$
0
6
$\begingroup$

I modified some of the above script to duplicate mesh objects around the golden radius in a sphere.

Trippy Faces:

enter image description here https://www.youtube.com/watch?v=wPXOz7Xqf1g

Make sure one object is selected, then run the script. Also make sure the objects rotation,scale and location have been applied.

GR_Generator_Script:

import bpy
import bmesh
import math
from mathutils import Vector

n = 400 # number of points
r = 3 #radius
ob = bpy.context.object
obs = []
sce = bpy.context.scene

for i in range(1, n):
    theta = i * math.radians(137.5)#degrees
    phi =  (math.radians(180)/n) * i
    x = r*math.sin(phi)*math.cos(theta)
    y = r*math.sin(phi)*math.sin(theta)
    z = r*math.cos(phi)

    if x<0:
        a = x*(-1)
    else:
        a = x

    if y < 0: 
        b = y*(-1)
    else:
        b = y         

    c = math.sqrt((a*a)+(b*b))
    size = 0.06+(c*0.09) #This can be messed about with to get the right size

    copy = ob.copy()
    copy.location = (x,y,z)
    copy.scale = (size,size,size)

    copy.rotation_euler=(phi,math.radians(0),theta+math.radians(90))

    copy.data = copy.data.copy()
    obs.append(copy)

for ob in obs:
    sce.objects.link(ob)

sce.update() # don't place this in either of the above loops!

Once mesh objects have been generated, select them all and make one object (Ctrl-J). Then, making sure 3D Cursor is at 0,0,0 (Shift-C) click Object->Transform->Origin to 3D Cursor

Then you can run the

Key_Frame_Generator:

import bpy
import bmesh
import math
from mathutils import Vector

# prepare a scene
scn = bpy.context.scene
ob = bpy.context.object

#number of frames
n = 143 
#degrees to rotate
d = 0 #Change to apply spin

for i in range(0, n):

    bpy.context.scene.frame_set(i)

    # do something with the object. A rotation, in this case
    ob.rotation_euler=(0.0,0.0,math.radians(d))

    d = (d + 137.5) #Change to subtract to change direction of appeared flow

    # create keyframe
    bpy.ops.anim.keyframe_insert_menu(type='Rotation')
$\endgroup$
5
$\begingroup$

Here is a comparison of 2 similar functions: a busy cat

The functions are made to be run in a loop, with N providing the total number of dots, and k is the current iteration of the loop. The first FCT is a phyllotaxis spiral formula, dont know how it works, perhaps it isnt meant for sunflowers with 10 000 seeds as it seems abit simple, the outer seeds might make straight lines, and the scond functiion uses phi, it is actually was originally from a code to make spheres with equally distributed dots, like disco balls, its on this website @ evenly-distributing-n-points-on-a-sphere. i just found these codes online in groups.

function sflo1 ( N:float,k:int):Vector3{//phi based pylospiral
//N=numpts  k=currentpt 
k=k;
var inc =  Mathf.PI  * ( 3 - Mathf.Sqrt ( 5 ) );
var off = 2 / N;
var y = k * off - 1 + (off / 2);
var r = Mathf.Sqrt (Mathf.Abs(y))  ;
var phi = k * inc;
return Vector3(-Mathf.Cos(phi)*r, 0, -Mathf.Sin(phi)*r); 

};

function sflo ( N:float,k:int):Vector3{//easy formula based on 137.5 pylospiral
var n = k;
var r=Mathf.Sqrt (n)*1/(Mathf.Sqrt (N));;
var t=137.5*pi/180*n;
return Vector3(r*Mathf.Cos(t),0, r*Mathf.Sin(t));
} 

function sflosq ( N:float,k:int):Vector3{//my own version it's stupid!
//N=numpts  k=currentpt 

var inc =  Mathf.PI  * ( 3 - Mathf.Sqrt ( 5 ) );
var off = 2 / N;
var y = k * off - 1 + (off / 2);
var r = Mathf.Sqrt (Mathf.Abs(y)) * Mathf.Sign(y) ;
var phi = k * inc;
return Vector3(Mathf.Asin(Mathf.Cos(phi))*r, 0, (-Mathf.Acos(Mathf.Sin(phi))+pi/2)*r); 

};
$\endgroup$
2
  • 1
    $\begingroup$ This is certainly useful, but it's not exactly an answer. Can you post the functions with a short explanation as well? $\endgroup$
    – CharlesL
    Commented Dec 31, 2013 at 14:52
  • 1
    $\begingroup$ Hi, The functions are made to be run in a loop, with N providing the total number of dots, and k is the current iteration of the loop. $\endgroup$ Commented Jan 1, 2014 at 0:24
2
$\begingroup$

No, Blender doesn't have any features specific to the modeling the golden-ratio, so I would suggest...

  • Take an image and use it as a reference, you can do this using a background image or an empty-image (empty object displaying an image).

  • If a reference image isn't accurate enough, you could write a small Python script which plots this shape, it wouldn't be so hard, and once you have this you might be able to further extend it to suit your purpose.

Your question is fairly vague as to how you intend to apply this shape to the objects you model, so for a more detailed answer you would need to ask a more specific question.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .