def solve_Z(A, B, C, D, radius): from math import sin, pi, copysign AB = B - A BC = C - B CD = D - C α1 = angle_between(-BC, AB) α2 = angle_between(-BC, CD) # print("AB, BC, CD=", AB, BC, CD) # print("α1, α2=", degrees(α1), degrees(α2)) γ = _solve_Z_angle(α1, α2, BC.norm(), radius) # print("γ=", degrees(γ)) eX1X2 = rotate(-BC, -γ) / BC.norm() # print("eX1X2=", eX1X2) x = radius / BC.norm() * (1 - sin(abs(α1 - γ))) / sin(abs(α1)) # print("x=", x) X = B + x * BC # print("X=", X) X1 = X - eX1X2 * radius X2 = X + eX1X2 * radius Aprime = X1 + rotate(X - X1, copysign(pi / 2, α1) + γ - α1) Dprime = X2 + rotate(X - X2, copysign(pi / 2, α2) + γ - α2) # print("line", A, Aprime) # print("arc2", Aprime, X1, X) # print("arc2", X, X2, Dprime) # print("line", Dprime, D) return ( [ _Line(A, Aprime), _Arc(Aprime, X1, X, α1 < 0), _Arc(X, X2, Dprime, α1 > 0) ], [Dprime, D], )
def intersect(p1, p2, x_bounds, y_bounds): intersect_list = list() last_intersect = None def rotate_bounds90(x_bounds, y_bounds, i_times): for i in range(i_times): x_bounds, y_bounds = ( (-y_bounds[1], -y_bounds[0]), (x_bounds[0], x_bounds[1]), ) return x_bounds, y_bounds for i in range(4): p1i, p2i = rotate(p1, i * pi / 2), rotate(p2, i * pi / 2) x_boundsi, y_boundsi = rotate_bounds90( x_bounds, y_bounds, i) p = intersect_left_boundary(p1i, p2i, x_boundsi, y_boundsi) if p is not None: last_intersect = i intersect_list.append(rotate(p, -i * pi / 2)) return intersect_list, last_intersect
def origin_ex_ey(self, multiple_of_90=False): # pylint: disable=unused-argument EX = kdb.DVector(1, 0) cp = self.get_cell_params() origin = kdb.DPoint(0, 0) # if 'angle_ex' not in cp.__dict__: # cp.angle_ex = 0 if multiple_of_90: if cp.angle_ex % 90 != 0: raise RuntimeError("Specify an angle multiple of 90 degrees") from math import pi ex = rotate(EX, cp.angle_ex * pi / 180) ey = rotate90(ex) return origin, ex, ey
def rotate(self, angle_deg): from zeropdk.layout.geometry import rotate from math import pi self.direction = rotate(self.direction, angle_deg * pi / 180) return self