Beispiel #1
0
def add_wire_straight(pnts, net, layer, width, radius=0):
    rpnts = []
    for idx, curr in enumerate(pnts):
        if idx == 0 or idx + 1 == len(pnts):  # first or last
            rpnts.append(curr)
            continue
        prev = pnts[idx - 1]
        next = pnts[idx + 1]
        vec_a = vec2.sub(prev, curr)
        vec_b = vec2.sub(next, curr)
        len_a = vec2.length(vec_a)
        len_b = vec2.length(vec_b)
        length = min(abs(radius), len_a / 2 if idx - 1 > 0 else len_a,
                     len_b / 2 if idx + 1 < len(pnts) - 1 else len_b)
        if length < 10**(-PointDigits):
            rpnts.append(curr)
        else:
            if radius < 0:  # and abs( vec2.dot( vec_a, vec_b ) ) < len_a * len_b * 0.001:
                # bezier circle
                num_divs = 15
                cef = (math.sqrt(0.5) - 0.5) / 3 * 8
                bpnts = []
                bpnts.append(vec2.scale(length / len_a, vec_a, curr))
                bpnts.append(vec2.scale(length / len_a * cef, vec_a, curr))
                bpnts.append(vec2.scale(length / len_b * cef, vec_b, curr))
                bpnts.append(vec2.scale(length / len_b, vec_b, curr))
                num_pnts = len(bpnts)
                tmp = [(0, 0) for n in range(num_pnts)]
                rpnts.append(bpnts[0])
                for i in range(1, num_divs):
                    t = float(i) / num_divs
                    s = 1 - t
                    for n in range(num_pnts):
                        tmp[n] = bpnts[n]
                    for L in range(num_pnts - 1, 0, -1):
                        for n in range(L):
                            tmp[n] = vec2.scale(s, tmp[n],
                                                vec2.scale(t, tmp[n + 1]))
                    rpnts.append(tmp[0])
                rpnts.append(bpnts[-1])
            else:
                rpnts.append(vec2.scale(length / len_a, vec_a, curr))
                rpnts.append(vec2.scale(length / len_b, vec_b, curr))
    for idx, curr in enumerate(rpnts):
        if idx == 0:
            continue
        prev = rpnts[idx - 1]
        if vec2.distance(prev, curr) > 0.01:
            add_track(prev, curr, net, layer, width)
Beispiel #2
0
def W(r, h):  # :: Num
    '''
    A weighting function (kernel) for the contribution of each neighbor
    to a particle's density. Forms a nice smooth gradient from the center 
    of a particle to H, where it's 0
    '''
    assert isinstance(r, Vec2)
    assert isinstance(h, Num)
    if 0 < length(r) <= h:
        return 315/(64 * pi * h**9) * (h**2 - length(r)**2)**3
    else:
        return 0

    # Typecheck
    assert isinstance(ret, Num)
    return ret
Beispiel #3
0
def intersectCircleCircle(c0P, c0R, c1P, c1R):
    v = vec2.sub(c1P, c0P)
    d = vec2.length(v)

    R = c0R
    r = c1R

    try:
        x = (d * d - r * r + R * R) / (2 * d)
    except ZeroDivisionError:
        if R < r:
            return 'inside', ()
        elif r > R:
            return 'outside', ()
        else:
            return 'coincident', ()

    k = R * R - x * x
    if k < 0:
        if x < 0:
            return 'inside', ()
        else:
            return 'outside', ()
    else:
        y = math.sqrt(k)
        return 'intersect', (vec2.toangle(v), vec2.toangle((x, y)))
Beispiel #4
0
def intersectCircleCircle(c0P, c0R, c1P, c1R):
	v = vec2.sub(c1P, c0P)
	d = vec2.length(v)
	
	R = c0R
	r = c1R

	try:	
		x = (d*d - r*r + R*R)/(2*d)
	except ZeroDivisionError:
		if R<r:
			return 'inside',()
		elif r>R:
			return 'outside',()
		else:
			return 'coincident',()
	
	k = R*R - x*x
	if k<0:
		if x<0:
			return 'inside',()
		else:
			return 'outside',()
	else:
		y = math.sqrt(k)
		return 'intersect',(vec2.toangle(v),vec2.toangle((x,y)))
Beispiel #5
0
def W(r, h):  # :: Num
    '''
    A weighting function (kernel) for the contribution of each neighbor
    to a particle's density. Forms a nice smooth gradient from the center 
    of a particle to H, where it's 0
    '''
    assert isinstance(r, Vec2)
    assert isinstance(h, Num)
    if 0 < length(r) <= h:
        return 315 / (64 * pi * h**9) * (h**2 - length(r)**2)**3
    else:
        return 0

    # Typecheck
    assert isinstance(ret, Num)
    return ret
Beispiel #6
0
def laplacian_W_viscosity(r, h):  # :: Num
    '''
    The laplacian of a weighting function that tends towards infinity when 
    approching 0 (slows down particles moving faster than their neighbors)
    '''
    len_r = length(r)

    if 0 < len_r <= h:
        ret = 45/(2 * pi * h**5) * (1 - len_r/h)
    else:
        ret = 0

    assert isinstance(ret, Num)
    return ret
Beispiel #7
0
def laplacian_W_viscosity(r, h):  # :: Num
    '''
    The laplacian of a weighting function that tends towards infinity when 
    approching 0 (slows down particles moving faster than their neighbors)
    '''
    len_r = length(r)

    if 0 < len_r <= h:
        ret = 45 / (2 * pi * h**5) * (1 - len_r / h)
    else:
        ret = 0

    assert isinstance(ret, Num)
    return ret
Beispiel #8
0
def gradient_Wspiky(r, h):  # :: Vec2
    '''
    Gradient ( that is, Vec2(dx, dy) ) of a weighting function for
    a particle's pressure. This weight function is spiky (not flat or
    smooth at x=0) so particles close together repel strongly
    '''
    len_r = length(r)

    if 0 < len_r <= h:
        ret =  -1 * r * (45/(pi * h**6 * len_r)) * (h - len_r)**2
    else:
        ret = Vec2(0, 0)

    assert isinstance(ret, Vec2)
    return ret
Beispiel #9
0
def gradient_Wspiky(r, h):  # :: Vec2
    '''
    Gradient ( that is, Vec2(dx, dy) ) of a weighting function for
    a particle's pressure. This weight function is spiky (not flat or
    smooth at x=0) so particles close together repel strongly
    '''
    len_r = length(r)

    if 0 < len_r <= h:
        ret = -1 * r * (45 / (pi * h**6 * len_r)) * (h - len_r)**2
    else:
        ret = Vec2(0, 0)

    assert isinstance(ret, Vec2)
    return ret
Beispiel #10
0
def drawRect(pnts, layer, R=75, width=2):
    if R > 0:
        arcs = []
        for idx, a in enumerate(pnts):
            b = pnts[idx - 1]
            vec = vec2.sub(b, a)
            length = vec2.length(vec)
            delta = vec2.scale(R / length, vec)
            na = vec2.add(a, delta)
            nb = vec2.sub(b, delta)
            ctr = vec2.add(nb, (delta[1], -delta[0]))
            arcs.append((ctr, na, nb))
            add_line(na, nb, layer, width)
        for idx, (ctr, na, nb) in enumerate(arcs):
            arc = add_arc2(ctr, nb, arcs[idx - 1][1], -90, layer, width)
            # print( "na   ", pnt.mils2unit( vec2.round( na ) ) )
            # print( "start", arc.GetArcStart() )
            # print( "nb   ", pnt.mils2unit( vec2.round( nb ) ) )
            # print( "end  ", arc.GetArcEnd() )
    else:
        for idx, a in enumerate(pnts):
            b = pnts[idx - 1]
            add_line(a, b, layer, width)
Beispiel #11
0
while True:

    # Clear everything
    for particle in particles:
        particle.density = DENSITY
        particle.pressure_force = Vec2(0,0)
        particle.viscosity_force = Vec2(0,0)
    
    # Calculate fluid density around each particle
    for particle in particles:
        for neighbor in particles:

            # If particles are close together, density increases
            distance = particle.position - neighbor.position # A vector

            if length(distance) <= H:  # Particles are close enough to matter
                particle.density += MASS * W(distance, H)

    # Calculate forces on each particle based on density
    for particle in particles:
        for neighbor in particles:

            distance = particle.position - neighbor.position
            if length(distance) <= H:
                # Temporary terms used to caclulate forces
                density_p = particle.density
                density_n = neighbor.density
                assert(density_n != 0)  # Dividing by density later

                # Pressure derived from the ideal gas law (constant temp)
                pressure_p = k * (density_p - DENSITY)
Beispiel #12
0
while True:

    # Clear everything
    for particle in particles:
        particle.density = DENSITY
        particle.pressure_force = Vec2(0, 0)
        particle.viscosity_force = Vec2(0, 0)

    # Calculate fluid density around each particle
    for particle in particles:
        for neighbor in particles:

            # If particles are close together, density increases
            distance = particle.position - neighbor.position  # A vector

            if length(distance) <= H:  # Particles are close enough to matter
                particle.density += MASS * W(distance, H)

    # Calculate forces on each particle based on density
    for particle in particles:
        for neighbor in particles:

            distance = particle.position - neighbor.position
            if length(distance) <= H:
                # Temporary terms used to caclulate forces
                density_p = particle.density
                density_n = neighbor.density
                assert (density_n != 0)  # Dividing by density later

                # Pressure derived from the ideal gas law (constant temp)
                pressure_p = k * (density_p - DENSITY)