예제 #1
0
def make_ovoidal_spiral(settings):
    '''
        eR       : exterior radius (vertical cross section circles)
        iR       : interior radius (horizontal cross section circle)
        exponent : rate of growth (sigmoid in & out)
        turns    : number of turns in the spiral
        N        : the curve resolution of one turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    max_phi = 2 * pi * turns * sign

    # derive eR based on iR and height (the main parameters)
    # eR = [iR - (H/2)^2/iR]/2 ::: H = 2 * sqrt(2*iR*eR - iR*iR)
    eR = 0.5 * (iR + 0.25 * height * height / iR)
    eR2 = eR * eR  # cached for performance
    dR = eR - iR  # cached for performance

    N = N * turns  # total number of points in the spiral

    es = prepareExponentialSettings(2, exponent + 1e-5)  # used for easing

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        t = n / N  # t : [0, 1]
        phi = max_phi * t + phase
        a = ExponentialEaseInOut(t, es)  # ease theta variation
        theta = -pi / 2 + pi * a
        h = 0.5 * height * sin(theta)  # [-H/2, +H/2]
        r = sqrt(eR2 - h * h) - dR  # [0 -> iR -> 0]
        x = r * cos(phi) * scale
        y = r * sin(phi) * scale
        z = h * scale
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #2
0
def make_spirangle_spiral(settings):
    '''
        eR       : exterior radius (end radius)
        iR       : interior radius (start radius)
        exponent : rate of growth
        turns    : number of turns in the spiral
        N        : curve resolution per turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    deltaA = 2 * pi / N * sign  # angle increment
    deltaE = exponent / N  # exponent increment
    deltaR = (eR + iR)  # radius increment
    deltaZ = height / (N * turns)  # z increment
    e = 0
    r = iR
    phi = phase
    x, y, z = [0, 0, -deltaZ]

    N = N * turns  # total number of points in the spiral

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        x = x + r * cos(phi) * scale
        y = y + r * sin(phi) * scale
        z = z + deltaZ
        e = e + deltaE
        r = r + deltaR * exp(e)
        phi = phi + deltaA
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #3
0
def make_spherical_spiral(settings):
    '''
        This is the approximate sperical spiral that has a finite length,
        where the phi & theta angles sweep their ranges at constant rates.

        eR       : exterior radius
        iR       : interior radius (UNUSED)
        exponent : rate of growth (sigmoid in & out)
        turns    : number of turns in the spiral
        N        : the curve resolution of one turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z (UNUSED)
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    max_phi = 2 * pi * turns * sign

    N = N * turns  # total number of points in the spiral

    es = prepareExponentialSettings(2, exponent + 1e-5)  # used for easing

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        t = n / N  # t : [0, 1]
        phi = max_phi * t + phase
        a = ExponentialEaseInOut(t, es)  # ease theta variation
        theta = -pi / 2 + pi * a
        RxCosTheta = (iR + eR * cos(theta)) * scale  # cached for performance
        x = cos(phi) * RxCosTheta
        y = sin(phi) * RxCosTheta
        z = eR * sin(theta)
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #4
0
def make_archimedean_spiral(settings):
    '''
        eR       : exterior radius (end radius)
        iR       : interior radius (start radius)
        exponent : rate of growth (between iR and eR)
        turns    : number of turns in the spiral
        N        : curve resolution per turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    max_phi = 2 * pi * turns * sign

    epsilon = 1e-5 if exponent < 0 else 0  # to avoid raising zero to negative power
    exponent = 1e-2 if exponent == 0 else exponent  # to avoid division by zero
    dR = eR - iR  # radius range : cached for performance
    ex = 1 / exponent  # inverse exponent : cached for performance

    N = N * turns  # total number of points in the spiral

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        t = n / N  # t : [0, 1]
        phi = max_phi * t + phase
        r = (iR + dR *
             (t + epsilon)**ex) * scale  # essentially: r = a * t ^ (1/b)
        x = r * cos(phi)
        y = r * sin(phi)
        z = height * t
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #5
0
def make_exo_spiral(settings):
    '''
        This is an exponential in & out between two circles

        eR       : exterior radius
        iR       : interior radius
        exponent : rate of growth (SIGMOID : exponential in & out)
        turns    : number of turns in the spiral
        N        : the curve resolution of one turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = 1 if flip else -1  # flip direction ?

    max_phi = 2 * pi * turns * sign

    N = N * turns  # total number of points in the spiral

    es = prepareExponentialSettings(11, exponent + 1e-5)  # used for easing

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        t = n / N  # t : [0, 1]
        a = ExponentialEaseInOut(t, es)  # ease radius variation (SIGMOID)
        r = (iR + (eR - iR) * a) * scale
        phi = max_phi * t + phase
        x = r * cos(phi)
        y = r * sin(phi)
        z = height * t
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #6
0
def make_logarithmic_spiral(settings):
    '''
        eR       : exterior radius
        iR       : interior radius
        exponent : rate of growth
        turns    : number of turns in the spiral
        N        : curve resolution per turn
        scale    : overall scale of the curve
        height   : the height of the spiral along z
        phase    : phase the spiral around its center
        flip     : flip the spiral direction (default is CLOCKWISE)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    max_phi = 2 * pi * turns

    N = N * turns  # total number of points in the spiral

    verts = []
    norms = []
    add_vert = verts.append
    add_norm = norms.append
    for n in range(N + 1):
        t = n / N  # t : [0, 1]
        phi = max_phi * t
        r = eR * exp(exponent * phi) * scale  # essentially: r = a * e ^ (b*t)
        pho = phi * sign + phase  # final angle : cached for performance
        x = r * sin(pho)
        y = r * cos(pho)
        z = height * t
        add_vert([x, y, z])

    edges = get_edge_list(N)

    return verts, edges, norms
예제 #7
0
def make_cornu_spiral(settings):
    '''
        L     : length
        N     : resolution
        S     : scale
        M     :

        x(t) = s * Integral(0,t) { cos(pi*u*u/2) du }
        y(t) = s * Integral(0,t) { sin(pi*u*u/2) du }

        TODO : refine the math (smoother curve, adaptive res, faster computation)
    '''

    eR, iR, exponent, turns, N, scale, height, phase, flip = settings

    sign = -1 if flip else 1  # flip direction ?

    N = N * turns  # total number of points in the spiral
    L = iR * turns  # length
    S = eR * scale  # overall scale

    es = prepareExponentialSettings(2, exponent + 1e-5)  # used for easing

    verts1 = []  # pozitive spiral verts
    verts2 = []  # nagative spiral verts
    norms = []
    add_vert1 = verts1.append
    add_vert2 = verts2.append
    add_norm = norms.append
    l1 = 0
    x = 0
    y = 0
    for n in range(N + 1):
        t = n / N  # t = [0,1]

        a = QuadraticEaseOut(t)
        # a = ExponentialEaseOut(t, es)

        l = L * a  # l = [0, +L]

        r = x * x + y * y
        # print("r=", r)
        # M = 100 + int(300 * pow(r, exponent)) # integral steps
        M = 100 + int(100 * a)  # integral steps
        l2 = l

        # integral from l1 to l2
        u = l1
        du = (l2 - l1) / M
        for m in range(M + 1):
            u = u + du  # u = [l1, l2]
            phi = u * u * pi / 2
            x = x + cos(phi) * du
            y = y + sin(phi) * du
        l1 = l2

        # scale and flip
        xx = x * S
        yy = y * S * sign

        # rotate by phase amount
        px = xx * cos(phase) - yy * sin(phase)
        py = xx * sin(phase) + yy * cos(phase)
        pz = height * t

        add_vert1([px, py, pz])  # positive spiral verts
        add_vert2([-px, -py, -pz])  # netative spiral verts

    verts = verts2[::-1] + verts1

    edges = get_edge_list(N)

    return verts, edges, norms