#! python 2 ############################## # final.PROJECT: female icons # friendship bracelets wrapped around the Empire State Building ############################## import math import sys import os import random import colorsys ############################## import rhinoscriptsyntax as rs sys.path.append("/Users/anny.more/Documents/studium/5. semester/DM2") sys.path.append("P:/") sys.path.append("C:/Users/c4ffrey/Documents/Rhino/") import DM_lib as dm ############################## rs.UnitSystem(4) rs.ShowGrid(None, 0) rs.ShowGridAxes(None, 1) rs.ViewDisplayMode(rs.CurrentView(), "arctic") rs.Command("cplane w t enter", 0) dm.PointRadius(displayModeX=0, rad=3, styl=3) dm.printDisplay(1) rs.EnableRedraw(0) ############################## ## Settings folder = "C:\\Users\\c4ffrey\\Documents\\Rhino\\animation\\" seconds = 8 framerate = 30 rotations = 2 number_of_beads = 13 color_change_seconds = 0.5 ## Settings END ######################################################################################### # HELIX ######################################################################################### helix_color = (150, 50, 100) # Top of the ESB # print rs.GetObject() points = dm.getSurfacePoints('bbf2dcc5-17b4-43a8-95f6-d2a27887e12d') start = None n = 0 for point in points: if point.Z > 0: if start: start = rs.VectorAdd(start, point) else: start = point n += 1 start = rs.VectorDivide(start, n) def create_helix(turns=5, base_radius=50): base_point = [start.X, start.Y, 0] helix_points = [] for i in range(turns * 50): angle = i / 50 * 360 threshold = 120 radius = base_radius if i <= threshold else base_radius * (1 - (i - threshold) / (turns * 50 - threshold)) v = [radius, radius, start.Z * i / (turns * 50)] v = rs.VectorRotate(v, angle, (0, 0, 1)) helix_points.append(rs.VectorAdd(v, base_point)) helix_curve = rs.AddCurve(helix_points) rs.ObjectColor(helix_curve, helix_color) rs.ObjectPrintWidth(helix_curve, 1) return helix_points ######################################################################################### # BEADS ######################################################################################### class Decoration: def __init__(self, step=2, amount=50): self.step = step self.amount = amount def sphere(r, n, c, step=1): golden_ratio = (1 + 5. ** 0.5) / 2 for i in range(0, n, step): theta = i / golden_ratio * 360 phi = math.acos(1 - 2*i/float(n)) v = (math.sin(phi), math.sin(phi), math.cos(phi)) v = rs.VectorScale(rs.VectorUnitize(rs.VectorRotate(v, theta, (0, 0, 1))), r) p = rs.AddPoint(rs.VectorAdd(c, v)) rs.ObjectPrintWidth(p, 4) yield p def decorated_sphere(center, d, size, color): for p in sphere(size, 500, center): rs.ObjectColor(p, color) rs.CurrentLayer("taylor::decorations") for p in sphere(size+1, d.amount, center, d.step): rs.ObjectColor(p, (255, 255, 255)) def circle(r, n, c): for i in range(n): v = rs.VectorRotate((r, 0, 0), i/n*360, (0, 0, 2)) yield rs.VectorAdd(c, v) def colors_between(colors_a, colors_b, percent): # hsv_a = [colorsys.rgb_to_hsv(*[v/255 for v in c]) for c in colors_a] # hsv_b = [colorsys.rgb_to_hsv(*[v/255 for v in c]) for c in colors_b] between = [[a + (b-a) * percent for a, b in zip(c_a, c_b)] for c_a, c_b in zip(colors_a, colors_b)] # rgb = [colorsys.hsv_to_rgb(*c) for c in between] return between #[[int(v*255) for v in c] for c in rgb] def draw(n, colors, decorations): dm.newEmptyLayer("taylor") dm.newEmptyLayer("helix", parent="taylor") points = create_helix() dm.newEmptyLayer("decorations", parent="taylor") for i in range(n): dm.newEmptyLayer("bead-"+str(i), parent="taylor") center = points[int(40 + (len(points) - 70) / n * i)] decorated_sphere(center, decorations[i], 20-i, colors[i]) yield center def recolor_beads(n, colors): for i in range(n): rs.ObjectColor(rs.ObjectsByLayer("taylor::bead-"+str(i)), colors[i]) def redecorate_beads(n, centers, decorations): dm.newEmptyLayer("decorations", parent="taylor") for i in range(n): for p in sphere(20-i+1, decorations[i].amount, centers[i], decorations[i].step): rs.ObjectColor(p, (255, 255, 255)) colors = [ (255, 105, 180), (34, 139, 34), (0, 150, 139), (205, 133, 63), (255, 60, 122), (186, 85, 211), (255, 105, 180), (100, 50, 139), (0, 100, 255), (255, 160, 122), (186, 85, 211), (255, 160, 122), (34, 139, 34) ] decorations = [ Decoration(1, 50), Decoration(3, 150), Decoration(4, 300), Decoration(5, 500), Decoration(6, 600), Decoration(7, 700), Decoration(2, 200), Decoration(3, 150), Decoration(2, 200), Decoration(1, 50), Decoration(5, 500), Decoration(3, 300), Decoration(5, 500) ] if not os.path.exists(folder): os.makedirs(folder) else: files = os.listdir(folder) [os.remove(os.path.join(folder, f)) for f in files if os.path.isfile(os.path.join(folder, f)) and "bracelets" in f] i = 0 frames = seconds * framerate frames_between_color_change = color_change_seconds * framerate color_sequence = [[random.choice(colors) for _ in range(number_of_beads)] for _ in range(int(frames/frames_between_color_change + 0.5) + 1)] decorations = [[random.choice(decorations) for _ in range(number_of_beads)] for _ in range(int(frames/frames_between_color_change + 0.5) + 1)] centers = list(draw(number_of_beads, color_sequence[0], decorations[0])) for _ in range(rotations): for camera_position in circle(500, int(frames/rotations), start): previous_colors = color_sequence[int(i / frames_between_color_change)] next_colors = color_sequence[int(i / frames_between_color_change) + 1] percent = (i % frames_between_color_change) / float(frames_between_color_change) current_colors = colors_between(previous_colors, next_colors, percent) previous_decorations = decorations[int(i / frames_between_color_change)] next_decorations = decorations[int(i / frames_between_color_change) + 1] current_decorations = [Decoration(p.step + int((n.step - p.step) * percent), p.amount + int((n.amount - p.amount) * percent)) for p, n in zip(previous_decorations, next_decorations)] recolor_beads(number_of_beads, current_colors) redecorate_beads(number_of_beads, centers, current_decorations) dm.setCameraTarget(camera_position, (start.X, start.Y, 200), lens=40) rs.Redraw() frame = dm.makeName("bracelets", i, format='jpg') rs.Command("-viewCaptureToFile Width=1080 Height=1920 Scale=1 DrawCPlaneAxes=No TransparentBackground=No "+folder+frame+" ", 0) i+=1