Ejemplo n.º 1
0
 def bound(self, state):
     c, r, a = self.center_radius_angle(state.m)
     # Use derivative of ellipse equation to find angle of min max points
     tx = dmath.atan2(-r[1] * dmath.sin(a[0]), -r[0] * dmath.cos(a[0]))
     ty = dmath.atan2(r[1] * dmath.cos(a[0]), -r[0] * dmath.sin(a[0]))
     # plug those numbers back into the ellipse equations
     dx = dmath.fabs(r[0] * dmath.cos(tx) * dmath.cos(a[0]) - r[1] * dmath.sin(tx) * dmath.sin(a[0]))
     dy = dmath.fabs(r[0] * dmath.cos(ty) * dmath.sin(a[0]) + r[1] * dmath.sin(ty) * dmath.cos(a[0]))
     return ((c[0] - dx, c[1] - dy), (c[0] + dx, c[1] + dy))
Ejemplo n.º 2
0
 def center_radius_angle(self, m):
     points = xform(m, self.points)
     c = points[0]
     r, a = [], []
     for p in points[1:]:
         dx, dy = p[0] - c[0], p[1] - c[1]
         r.append(dmath.hypot(dx, dy))
         a.append(dmath.atan2(-dy, dx))
     return c, r, a
Ejemplo n.º 3
0
    def rect_pad(self, name, points, rounded, state):
        m = []
        ret = []
        for i in range(len(points)):
            p0, p1 = points[i], points[(i + 1) % len(points)]
            m.append(((p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2))
        dim0 = dmath.hypot(m[2][0] - m[0][0], m[2][1] - m[0][1])
        dim1 = dmath.hypot(m[3][0] - m[1][0], m[3][1] - m[1][1])

        c = ((m[0][0] + m[2][0]) / 2, (m[0][1] + m[2][1]) / 2)

        if dim0.quantize(D("0.000001")) == dim1.quantize(D("0.000001")):
            if rounded:
                ret.append(circ_pad(name, c, dim0 / 2), state)
            else:
                ret += self.rect_pad(name, [ points[0], points[1], m[1], m[3] ], False, state)
                ret += self.rect_pad(name, [ m[3], m[1], points[2], points[3] ], False, state)
            return ret
        if dim0 > dim1:
            angle = dmath.atan2(m[2][1] - m[0][1], m[2][0] - m[0][0])
        else:
            angle = dmath.atan2(m[3][1] - m[1][1], m[3][0] - m[1][0])

        flags = []
        if not rounded:
            flags.append("square")
        if state.get_onsolder():
            flags.append("onsolder")
        if not state.get_paste():
            flags.append("nopaste")

        thickness = min(dim0, dim1) / 2
        width = max(dim0, dim1) - thickness * 2
        p = []
        p.append((c[0] + dmath.cos(angle) * width / 2, c[1] + dmath.sin(angle) * width / 2))
        p.append((c[0] - dmath.cos(angle) * width / 2, c[1] - dmath.sin(angle) * width / 2))
        ret.append("""Pad [ %s %s %s %s %s %s %s "%s" "%s" "%s" ]""" % (
            P(p[0][0]), P(p[0][1]), P(p[1][0]), P(p[1][1]), P(thickness * 2),
            P(self.clearance * 2), P((self.mask + thickness) * 2), name, name,
            ",".join(flags)))
        return ret
Ejemplo n.º 4
0
D2 = Decimal(2)

Vec = namedtuple("Vec", "x y")
vcross = lambda (a, b), (c, d): a*d - b*c
vdot   = lambda (a, b), (c, d): a*c + b*d
vadd   = lambda (a, b), (c, d): Vec(a + c, b + d)
vsub   = lambda (a, b), (c, d): Vec(a - c, b - d)
vlen   = lambda x: sqrt(vdot(x, x))
vdist  = lambda a, b: vlen(vsub(a, b))
vscale = lambda s, (x, y): Vec(x * s, y * s)

def vnorm(v):
    l = vlen(v)
    return Vec(v.x / l, v.y / l)

vangle = lambda (x, y): atan2(y, x)

def anorm(a):
    if a > pi:  return a - pi * D2
    if a < -pi: return a + pi * D2
    return             a

Circle = namedtuple("Circle", "x y r")

def circle_cross((x0, y0, r0), (x1, y1, r1)):
    d = vdist(Vec(x0, y0), Vec(x1, y1))
    if d >= r0 + r1 or d <= abs(r0 - r1):
        return []

    s = (r0 + r1 + d) / D2
    a = sqrt(s * (s - d) * (s - r0) * (s - r1))