Example #1
0
    def test_normal(self):
        surf = sf.sphere(1)
        surf.swap()
        u = np.linspace(surf.start(0) + 1e-3, surf.end(0) - 1e-3, 9)
        v = np.linspace(surf.start(1) + 1e-3, surf.end(1) - 1e-3, 9)

        xpts = surf(u, v, tensor=False)
        npts = surf.normal(u, v, tensor=False)

        self.assertEqual(npts.shape, (9, 3))

        # check that the normal is pointing out of the unit ball on a 9x9 evaluation grid
        for (x, n) in zip(xpts, npts):
            self.assertAlmostEqual(n[0], x[0])
            self.assertAlmostEqual(n[1], x[1])
            self.assertAlmostEqual(n[2], x[2])

        xpts = surf(u, v)
        npts = surf.normal(u, v)

        self.assertEqual(npts.shape, (9, 9, 3))

        # check that the normal is pointing out of the unit ball on a 9x9 evaluation grid
        for (i, j) in zip(xpts, npts):
            for (x, n) in zip(i, j):
                self.assertAlmostEqual(n[0], x[0])
                self.assertAlmostEqual(n[1], x[1])
                self.assertAlmostEqual(n[2], x[2])

        # check single value input
        n = surf.normal(0, 0)
        self.assertEqual(len(n), 3)

        # test 2D surface
        s = Surface()
        n = s.normal(.5, .5)
        self.assertEqual(len(n), 3)
        self.assertAlmostEqual(n[0], 0.0)
        self.assertAlmostEqual(n[1], 0.0)
        self.assertAlmostEqual(n[2], 1.0)
        n = s.normal([.25, .5], [.1, .2, .3, .4, .5, .6, .7, .8, .9])
        self.assertEqual(n.shape[0], 2)
        self.assertEqual(n.shape[1], 9)
        self.assertEqual(n.shape[2], 3)
        self.assertAlmostEqual(n[1, 4, 0], 0.0)
        self.assertAlmostEqual(n[1, 4, 1], 0.0)
        self.assertAlmostEqual(n[1, 4, 2], 1.0)

        n = s.normal([.25, .5, .75], [.3, .5, .9], tensor=False)
        self.assertEqual(n.shape, (3, 3))
        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(n[i, j], 0.0)
            self.assertAlmostEqual(n[i, 2], 1.0)

        # test errors
        s = Surface(BSplineBasis(3), BSplineBasis(3), [[0]] * 9)  # 1D-surface
        with self.assertRaises(RuntimeError):
            s.normal(.5, .5)
Example #2
0
 def test_sphere(self):
     # unit ball
     surf = SurfaceFactory.sphere()
     # test 7x7 grid for radius = 1
     for u in np.linspace(surf.start()[0], surf.end()[0], 7):
         for v in np.linspace(surf.start()[1], surf.end()[1], 7):
             self.assertAlmostEqual(np.linalg.norm(surf(u, v), 2), 1.0)
     self.assertAlmostEqual(surf.area(), 4*pi, places=3)
Example #3
0
 def test_sphere(self):
     # unit ball
     surf = sf.sphere()
     # test 7x7 grid for radius = 1
     for u in np.linspace(surf.start()[0], surf.end()[0], 7):
         for v in np.linspace(surf.start()[1], surf.end()[1], 7):
             self.assertAlmostEqual(np.linalg.norm(surf(u, v), 2), 1.0)
     self.assertAlmostEqual(surf.area(), 4 * pi, places=3)
Example #4
0
    def sphere(self):
        dim      = int(     self.read_next_non_whitespace().strip())
        r        = float(   next(self.fstream).strip())
        center   = np.array(next(self.fstream).split(), dtype=float)
        z_axis   = np.array(next(self.fstream).split(), dtype=float)
        x_axis   = np.array(next(self.fstream).split(), dtype=float)
        param_u  = np.array(next(self.fstream).split(), dtype=float)
        param_v  = np.array(next(self.fstream).split(), dtype=float)
        swap     =          next(self.fstream).strip() != '0'

        result = SurfaceFactory.sphere(r=r, center=center, xaxis=x_axis, zaxis=z_axis).swap()
        if swap:
            result.swap()
        result.reparam(param_u, param_v)
        return result
Example #5
0
def sphere(r=1, center=(0, 0, 0), type='radial'):
    """  Create a solid sphere

    :param float r: Radius
    :param array-like center: Local origin of the sphere
    :param string type: The type of parametrization ('radial' or 'square')
    :return: A solid ball
    :rtype: Volume
    """
    if type == 'radial':
        shell = SurfaceFactory.sphere(r, center)
        midpoint = shell * 0 + center
        return edge_surfaces(shell, midpoint)
    elif type == 'square':
        # based on the work of James E.Cobb: "Tiling the Sphere with Rational Bezier Patches"
        # University of Utah, July 11, 1988. UUCS-88-009
        b = BSplineBasis(order=5)
        sr2 = sqrt(2)
        sr3 = sqrt(3)
        sr6 = sqrt(6)
        cp = [
            [-4 * (sr3 - 1), 4 * (1 - sr3), 4 * (1 - sr3),
             4 * (3 - sr3)],  # row 0
            [-sr2, sr2 * (sr3 - 4), sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [
                0, 4. / 3 * (1 - 2 * sr3), 4. / 3 * (1 - 2 * sr3),
                4. / 3 * (5 - sr3)
            ],
            [sr2, sr2 * (sr3 - 4), sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [4 * (sr3 - 1), 4 * (1 - sr3), 4 * (1 - sr3), 4 * (3 - sr3)],
            [-sr2 * (4 - sr3), -sr2, sr2 * (sr3 - 4),
             sr2 * (3 * sr3 - 2)],  # row 1
            [
                -(3 * sr3 - 2) / 2, (2 - 3 * sr3) / 2, -(sr3 + 6) / 2,
                (sr3 + 6) / 2
            ],
            [0, sr2 * (2 * sr3 - 7) / 3, -5 * sr6 / 3, sr2 * (sr3 + 6) / 3],
            [(3 * sr3 - 2) / 2, (2 - 3 * sr3) / 2, -(sr3 + 6) / 2,
             (sr3 + 6) / 2],
            [sr2 * (4 - sr3), -sr2, sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [
                -4. / 3 * (2 * sr3 - 1), 0, 4. / 3 * (1 - 2 * sr3),
                4 * (5 - sr3) / 3
            ],  # row 2
            [-sr2 / 3 * (7 - 2 * sr3), 0, -5 * sr6 / 3, sr2 * (sr3 + 6) / 3],
            [0, 0, 4 * (sr3 - 5) / 3, 4 * (5 * sr3 - 1) / 9],
            [sr2 / 3 * (7 - 2 * sr3), 0, -5 * sr6 / 3, sr2 * (sr3 + 6) / 3],
            [
                4. / 3 * (2 * sr3 - 1), 0, 4. / 3 * (1 - 2 * sr3),
                4 * (5 - sr3) / 3
            ],
            [-sr2 * (4 - sr3), sr2, sr2 * (sr3 - 4),
             sr2 * (3 * sr3 - 2)],  # row 3
            [
                -(3 * sr3 - 2) / 2, -(2 - 3 * sr3) / 2, -(sr3 + 6) / 2,
                (sr3 + 6) / 2
            ],
            [0, -sr2 * (2 * sr3 - 7) / 3, -5 * sr6 / 3, sr2 * (sr3 + 6) / 3],
            [(3 * sr3 - 2) / 2, -(2 - 3 * sr3) / 2, -(sr3 + 6) / 2,
             (sr3 + 6) / 2],
            [sr2 * (4 - sr3), sr2, sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [-4 * (sr3 - 1), -4 * (1 - sr3), 4 * (1 - sr3),
             4 * (3 - sr3)],  # row 4
            [-sr2, -sr2 * (sr3 - 4), sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [
                0, -4. / 3 * (1 - 2 * sr3), 4. / 3 * (1 - 2 * sr3),
                4. / 3 * (5 - sr3)
            ],
            [sr2, -sr2 * (sr3 - 4), sr2 * (sr3 - 4), sr2 * (3 * sr3 - 2)],
            [4 * (sr3 - 1), -4 * (1 - sr3), 4 * (1 - sr3), 4 * (3 - sr3)]
        ]
        wmin = Surface(b, b, cp, rational=True)
        wmax = wmin.clone().mirror([0, 0, 1])
        vmax = wmin.clone().rotate(pi / 2, [1, 0, 0])
        vmin = vmax.clone().mirror([0, 1, 0])
        umax = vmin.clone().rotate(pi / 2, [0, 0, 1])
        umin = umax.clone().mirror([1, 0, 0])
        # ideally I would like to call edge_surfaces() now, but that function
        # does not work with rational surfaces, so we'll just manually try
        # and add some inner controlpoints
        cp = np.zeros((5, 5, 5, 4))
        cp[:, :, 0, :] = wmin[:, :, :]
        cp[:, :, -1, :] = wmax[:, :, :]
        cp[:, 0, :, :] = vmin[:, :, :]
        cp[:, -1, :, :] = vmax[:, :, :]
        cp[0, :, :, :] = umin[:, :, :]
        cp[-1, :, :, :] = umax[:, :, :]
        inner = np.linspace(-.5, .5, 3)
        Y, X, Z = np.meshgrid(inner, inner, inner)
        cp[1:4, 1:4, 1:4, 0] = X
        cp[1:4, 1:4, 1:4, 1] = Y
        cp[1:4, 1:4, 1:4, 2] = Z
        cp[1:4, 1:4, 1:4, 3] = 1
        ball = Volume(b, b, b, cp, rational=True, raw=True)
        return r * ball + center
    else:
        raise ValueError('invalid type argument')
Example #6
0
def sphere(r=1, center=(0,0,0), type='radial'):
    """  Create a solid sphere

    :param float r: Radius
    :param array-like center: Local origin of the sphere
    :param string type: The type of parametrization ('radial' or 'square')
    :return: A solid ball
    :rtype: Volume
    """
    if type == 'radial':
        shell    = SurfaceFactory.sphere(r, center)
        midpoint = shell*0 + center
        return edge_surfaces(shell, midpoint)
    elif type == 'square':
        # based on the work of James E.Cobb: "Tiling the Sphere with Rational Bezier Patches"
        # University of Utah, July 11, 1988. UUCS-88-009
        b = BSplineBasis(order=5)
        sr2 = sqrt(2)
        sr3 = sqrt(3)
        sr6 = sqrt(6)
        cp = [[      -4*(sr3-1),       4*(1-sr3),      4*(1-sr3),   4*(3-sr3)  ], # row 0
              [           -sr2 ,     sr2*(sr3-4),    sr2*(sr3-4), sr2*(3*sr3-2)],
              [              0 ,  4./3*(1-2*sr3), 4./3*(1-2*sr3),4./3*(5-sr3)  ],
              [            sr2 ,     sr2*(sr3-4),    sr2*(sr3-4), sr2*(3*sr3-2)],
              [       4*(sr3-1),       4*(1-sr3),      4*(1-sr3),   4*(3-sr3)  ],
              [    -sr2*(4-sr3),            -sr2,    sr2*(sr3-4), sr2*(3*sr3-2)], # row 1
              [    -(3*sr3-2)/2,     (2-3*sr3)/2,     -(sr3+6)/2,     (sr3+6)/2],
              [              0 , sr2*(2*sr3-7)/3,       -5*sr6/3, sr2*(sr3+6)/3],
              [     (3*sr3-2)/2,     (2-3*sr3)/2,     -(sr3+6)/2,     (sr3+6)/2],
              [     sr2*(4-sr3),            -sr2,    sr2*(sr3-4), sr2*(3*sr3-2)],
              [ -4./3*(2*sr3-1),               0, 4./3*(1-2*sr3),   4*(5-sr3)/3], # row 2
              [-sr2/3*(7-2*sr3),               0,       -5*sr6/3, sr2*(sr3+6)/3],
              [              0 ,               0,    4*(sr3-5)/3, 4*(5*sr3-1)/9],
              [ sr2/3*(7-2*sr3),               0,       -5*sr6/3, sr2*(sr3+6)/3],
              [  4./3*(2*sr3-1),               0, 4./3*(1-2*sr3),   4*(5-sr3)/3],
              [    -sr2*(4-sr3),             sr2,    sr2*(sr3-4), sr2*(3*sr3-2)], # row 3
              [    -(3*sr3-2)/2,    -(2-3*sr3)/2,     -(sr3+6)/2,     (sr3+6)/2],
              [              0 ,-sr2*(2*sr3-7)/3,       -5*sr6/3, sr2*(sr3+6)/3],
              [     (3*sr3-2)/2,    -(2-3*sr3)/2,     -(sr3+6)/2,     (sr3+6)/2],
              [     sr2*(4-sr3),             sr2,    sr2*(sr3-4), sr2*(3*sr3-2)],
              [      -4*(sr3-1),      -4*(1-sr3),      4*(1-sr3),   4*(3-sr3)  ], # row 4
              [           -sr2 ,    -sr2*(sr3-4),    sr2*(sr3-4), sr2*(3*sr3-2)],
              [              0 , -4./3*(1-2*sr3), 4./3*(1-2*sr3),4./3*(5-sr3)  ],
              [            sr2 ,    -sr2*(sr3-4),    sr2*(sr3-4), sr2*(3*sr3-2)],
              [       4*(sr3-1),      -4*(1-sr3),      4*(1-sr3),   4*(3-sr3)  ]]
        wmin = Surface(b,b,cp, rational=True)
        wmax = wmin.clone().mirror([0,0,1])
        vmax = wmin.clone().rotate(pi/2, [1,0,0])
        vmin = vmax.clone().mirror([0,1,0])
        umax = vmin.clone().rotate(pi/2, [0,0,1])
        umin = umax.clone().mirror([1,0,0])
        # ideally I would like to call edge_surfaces() now, but that function
        # does not work with rational surfaces, so we'll just manually try
        # and add some inner controlpoints
        cp   = np.zeros((5,5,5,4))
        cp[ :, :, 0,:] = wmin[:,:,:]
        cp[ :, :,-1,:] = wmax[:,:,:]
        cp[ :, 0, :,:] = vmin[:,:,:]
        cp[ :,-1, :,:] = vmax[:,:,:]
        cp[ 0, :, :,:] = umin[:,:,:]
        cp[-1, :, :,:] = umax[:,:,:]
        inner = np.linspace(-.5,.5, 3)
        Y, X, Z = np.meshgrid(inner,inner,inner)
        cp[1:4,1:4,1:4,0] = X
        cp[1:4,1:4,1:4,1] = Y
        cp[1:4,1:4,1:4,2] = Z
        cp[1:4,1:4,1:4,3] = 1
        ball = Volume(b,b,b,cp,rational=True, raw=True)
        return r*ball + center
    else:
        raise ValueError('invalid type argument')