10 Feb 2015

Summary: A sinusoidally generated ramen brick.

Instant ramen anticipated the maker movement by nearly forty years, and today it remains the undisputed Arduino of food: cheap, versatile and multicultural. My personal relationship with instant ramen began at a young age. Instant ramen allowed me to connect with my Japanese roots in an area of upstate New York that was devoid of asians.

I used Rhino and Python to generate my ramen brick. I relied on both sine and random functions to ensure that the noodles were structured in a way that was neither precise nor erratic. The most important part of the code is a triply nested for loop that builds the noodles up in layers. If I were to iterate on this project, I’d try to optimize it so that the resulting 3D file is smaller.

Part of the code is based on Robert McNeel’s Flatworm example from the RhinoScript 101 manual.


Ramen Brick
by mlsptn
on Sketchfab

import rhinoscriptsyntax as rs
import random
import math

def noodle():
    crvdomain = rs.CurveDomain(curve_object)
    crosssections = []
    t_step = (crvdomain[1]-crvdomain[0])/samples
    t = crvdomain[0]
    while t<=crvdomain[1]:
        crvcurvature = rs.CurveCurvature(curve_object, t)
        crosssectionplane = None
        if not crvcurvature:
            crvPoint = rs.EvaluateCurve(curve_object, t)
            crvTangent = rs.CurveTangent(curve_object, t)
            crvPerp = (0,0,1)
            crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp)
            crosssectionplane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNormal)
            crvPoint = crvcurvature[0]
            crvTangent = crvcurvature[1]
            crvPerp = rs.VectorUnitize(crvcurvature[4])
            crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp)
            crosssectionplane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNormal)

        if crosssectionplane:
            csec = rs.AddEllipse(crosssectionplane, bend_radius, perp_radius)
        t += t_step

    if not crosssections: return
    loftsrf = rs.AddLoftSrf(crosssections)

points_list = []
size = 400
depth = 50
num_layers = 7 
strands_per_layer = 50
strand_points = 85
wiggle = 10
layer_spacing = depth / num_layers
strand_spacing = size / strands_per_layer
pt_spacing = size / strand_points
offset_x = 0
offset_z = 0
offset_y = 0
curve_object = None

samples = strand_points
bend_radius = 2.5
perp_radius = 2.5

for layer in xrange(num_layers):
    for strand in xrange(strands_per_layer):
        for pt in xrange(strand_points):
            y = pt * pt_spacing + offset_y
            ang = pt 
            x = offset_x + math.sin(ang)*wiggle
            z = offset_z + random.randint(int(-wiggle/4),int(wiggle/4))
        offset_x += strand_spacing
        curve_object = rs.AddCurve(points_list) 
        points_list = []
    offset_x = random.randint(-wiggle,wiggle)
    offset_z += layer_spacing