예제 #1
0
 def test_arc_1(self):
     circle = SvCircle(Matrix(), 1.0)
     t_min = 0.1
     t_max = 1.4
     pt1 = circle.evaluate(t_max)
     nurbs = circle._arc_to_nurbs(t_min, t_max)
     pt2 = nurbs.evaluate(t_max)
     self.assert_numpy_arrays_equal(pt1, pt2, precision=8)
예제 #2
0
    def calc(point_a, point_b, tangent_a, tangent_b, p, planar_tolerance=1e-6):
        xx = point_b - point_a
        xx /= np.linalg.norm(xx)
        tangent_normal = np.cross(tangent_a, tangent_b)
        volume = np.dot(xx, tangent_normal)
        if abs(volume) > planar_tolerance:
            raise Exception(
                f"Provided tangents are not coplanar, volume={volume}")

        zz_a = np.cross(tangent_a, xx)
        zz_b = np.cross(tangent_b, xx)
        zz = (zz_a + zz_b)
        zz /= np.linalg.norm(zz)
        yy = np.cross(zz, xx)

        c = np.linalg.norm(point_b - point_a) * 0.5

        tangent_a /= np.linalg.norm(tangent_a)
        tangent_b /= np.linalg.norm(tangent_b)

        to_center_a = np.cross(zz, tangent_a)
        to_center_b = -np.cross(zz, tangent_b)

        matrix_inv = np.stack((xx, yy, zz))
        matrix = np.linalg.inv(matrix_inv)

        # TODO: sin(arccos(...)) = ...
        alpha = acos(np.dot(tangent_a, xx))
        beta = acos(np.dot(tangent_b, xx))
        if np.dot(tangent_a, yy) > 0:
            alpha = -alpha
        if np.dot(tangent_b, yy) > 0:
            beta = -beta
        #print("A", alpha, "B", beta)

        omega = (alpha + beta) * 0.5
        r1 = c / (sin(alpha) + sin(omega) / p)
        r2 = c / (sin(beta) + p * sin(omega))
        #print("R1", r1, "R2", r2)
        theta1 = 2 * arg(cexp(-1j * alpha) + cexp(-1j * omega) / p)
        theta2 = 2 * arg(cexp(1j * beta) + p * cexp(1j * omega))
        #print("T1", theta1, "T2", theta2)

        vectorx_a = r1 * to_center_a
        center1 = point_a + vectorx_a
        center2 = point_b + r2 * to_center_b

        arc1 = SvCircle(  #radius = r1,
            center=center1,
            normal=-zz,
            vectorx=point_a - center1)
        if theta1 > 0:
            arc1.u_bounds = (0.0, theta1)
        else:
            theta1 = -theta1
            arc1.u_bounds = (0.0, theta1)
            arc1.set_normal(-arc1.normal)

        junction = arc1.evaluate(theta1)
        #print("J", junction)

        arc2 = SvCircle(  #radius = r2,
            center=center2,
            normal=-zz,
            vectorx=junction - center2)
        if theta2 > 0:
            arc2.u_bounds = (0.0, theta2)
        else:
            theta2 = -theta2
            arc2.u_bounds = (0.0, theta2)
            arc2.set_normal(-arc2.normal)

        curve = SvBiArc(arc1, arc2)
        curve.p = p
        curve.junction = junction

        return curve