# radius of the cylindrical links or the rope radii = 0.1 ball_mass = 10 # radius of the wrecking ball ball_radius = 0.5 ball_color = np.array([[1, 0, 0]]) joint_friction = 0.0005 ############################################################################### # Creating the base plane actor. # Base base_actor = actor.box(centers=np.array([[0, 0, 0]]), directions=[0, 0, 0], scales=(5, 5, 0.2), colors=(1, 1, 1)) base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=[2.5, 2.5, 0.1]) base = p.createMultiBody(baseCollisionShapeIndex=base_coll, basePosition=[0, 0, -0.1], baseOrientation=[0, 0, 0, 1]) p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5) ############################################################################### # The following definitions are made to render a NxNxN brick wall. # Generate bricks. nb_bricks = wall_length * wall_breadth * wall_height brick_centers = np.zeros((nb_bricks, 3)) brick_directions = np.zeros((nb_bricks, 3))
# BALL ball_actor = actor.sphere(centers=np.array([[0, 0, 0]]), colors=np.array([1, 0, 0]), radii=0.3) ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=0.3) ball = p.createMultiBody(baseMass=3, baseCollisionShapeIndex=ball_coll, basePosition=[2, 0, 1.5], baseOrientation=[0, 0, 0, 1]) p.changeDynamics(ball, -1, lateralFriction=0.3, restitution=0.5) # BASE Plane base_actor = actor.box(centers=np.array([[0, 0, 0]]), directions=[0, 0, 0], size=(5, 5, 0.2), colors=(1, 1, 1)) base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=[2.5, 2.5, 0.1 ]) # half of the actual size. base = p.createMultiBody(baseCollisionShapeIndex=base_coll, basePosition=[0, 0, -0.1], baseOrientation=[0, 0, 0, 1]) p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5) height = 10 base_length = 10 brick_Ids = [] brick_actors = []
force=friction_vec) ############################################################################### # Next, we define a constraint base that will help us in the oscillation of the # chain. root_robe_c = p.createConstraint(rope, -1, -1, -1, p.JOINT_FIXED, [0, 0, 0], [0, 0, 0], [0, 0, 2]) # some traj to inject motion amplitude_x = 0.3 amplitude_y = 0.0 freq = 0.6 base_actor = actor.box(centers=np.array([[0, 0, 0]]), directions=np.array([[0, 0, 0]]), scales=(0.02, 0.02, 0.02), colors=np.array([[1, 0, 0]])) ############################################################################### # We add the necessary actors to the scene. scene = window.Scene() scene.background((1, 1, 1)) scene.set_camera((2.2, -3.0, 3.0), (-0.3, 0.6, 0.7), (-0.2, 0.2, 1.0)) scene.add(actor.axes(scale=(0.1, 0.1, 0.1))) scene.add(rope_actor) scene.add(base_actor) # Create show manager. showm = window.ShowManager(scene, size=(900, 768),
#BALL ball = actor.sphere(centers=np.array([[2, 3, 3]]), colors=np.array([1, 1, 1]), radii=0.6) ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=0.3) ball_vis = p.createVisualShape(p.GEOM_SPHERE, radius=0.3) ball_ = p.createMultiBody(baseMass=3, baseCollisionShapeIndex=ball_coll, baseVisualShapeIndex=ball_vis, basePosition=[2, 3, 3], baseOrientation=[0, 0, 0, 1]) p.changeDynamics(ball_, -1, lateralFriction=0.3, restitution=0.5) #BASE base = actor.box(centers=np.array([[-4, 3, -0.1]]), directions=[1.57, 0, 0], size=(20, 15, 0.2), colors=(0, 1, 0)) base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=[10, 7.5, 0.1]) base_vis = p.createVisualShape(p.GEOM_BOX, halfExtents=[10, 7.5, 0.1]) base_ = p.createMultiBody(baseVisualShapeIndex=base_vis, baseCollisionShapeIndex=base_coll, basePosition=[-4, 3, -0.1], baseOrientation=[0, 0, 0, 1]) p.changeDynamics(base_, -1, lateralFriction=0.3, restitution=0.5) height = 20 base_length = 20 brick_Ids = [] brick_actors = []
ball_coll = p.createCollisionShape(p.GEOM_SPHERE, radius=ball_radius) # Creating a multi-body which will be tracked by pybullet. ball = p.createMultiBody(baseMass=3, baseCollisionShapeIndex=ball_coll, basePosition=ball_position, baseOrientation=ball_orientation) # Change the dynamics of the ball by adding friction and restitution. p.changeDynamics(ball, -1, lateralFriction=0.3, restitution=0.5) ############################################################################### # Render a base plane to support the bricks. base_actor = actor.box(centers=np.array([[0, 0, 0]]), directions=[0, 0, 0], scales=base_size, colors=base_color) base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=base_size / 2) # half of the actual size. base = p.createMultiBody(baseCollisionShapeIndex=base_coll, basePosition=base_position, baseOrientation=base_orientation) p.changeDynamics(base, -1, lateralFriction=0.3, restitution=0.5) ############################################################################### # Now we render the bricks. All the bricks are rendered by a single actor for # better performance.
xyz = np.array([box_lx, box_ly, box_lz ]) * (np.random.rand(num_particles, 3) - 0.5) * 0.6 vel = 4 * (np.random.rand(num_particles, 3) - 0.5) colors = np.random.rand(num_particles, 3) radii = np.random.rand(num_particles) + 0.01 ############################################################################## # With box, streamtube and sphere actors, we can create the box, the # edges of the box and the spheres respectively. scene = window.Scene() box_centers = np.array([[0, 0, 0]]) box_directions = np.array([[0, 1, 0]]) box_colors = np.array([[1, 1, 1, 0.2]]) box_actor = actor.box(box_centers, box_directions, box_colors, scales=(box_lx, box_ly, box_lz)) scene.add(box_actor) lines = box_edges(box_lx, box_ly, box_lz) line_actor = actor.streamtube(lines, colors=(1, 0.5, 0), linewidth=0.1) scene.add(line_actor) sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii) scene.add(sphere_actor) showm = window.ShowManager(scene, size=(900, 768), reset_camera=True, order_transparent=True) showm.initialize()
p.setCollisionFilterPair(obj, wall, -1, -1, enableCol) p.setCollisionFilterPair(obj, wall_1, -1, -1, enableCol) # p.setRealTimeSimulation(1) xyz = np.array([[0, 0, 0]]) colors = np.array([[0.7, 0.5, 0.5, 1]]) radii = 0.5 scene = window.Scene() sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii) cuboid_actor = actor.box(centers=xyz, directions=np.array( p.getEulerFromQuaternion([ -0.4044981, -0.8089962, -0.4044981, 0.1352322 ])), size=(0.2, 0.2, 1), colors=(0, 1, 1)) wall_actor_1 = actor.box(centers=np.array([[-4, 0, 4]]), directions=np.array([[1.57, 0, 0]]), size=(0.2, 10, 10), colors=(1, 1, 1)) wall_actor_2 = actor.box(centers=np.array([[0, 0, 0]]), directions=np.array([[-1.57, 0, 0]]), size=(10, 10, 0.2), colors=(1, 1, 1)) scene.add(wall_actor_1)
ring_slider = ui.RingSlider2D(initial_value=0, text_template="{angle:5.1f}°") line_slider_x = ui.LineSlider2D(initial_value=0, min_value=-10, max_value=10, orientation="horizontal", text_alignment="Top") line_slider_y = ui.LineSlider2D(initial_value=0, min_value=-10, max_value=10, orientation="vertical", text_alignment="Right") cube = actor.box(centers=np.array([[10, 0, 0]]), directions=np.array([[0, 1, 0]]), colors=np.array([[0, 0, 1]]), scales=np.array([[1, 1, 1]])) cube_x = 0 cube_y = 0 def rotate_cube(slider): angle = slider.value previous_angle = slider.previous_value rotation_angle = angle - previous_angle cube.RotateX(rotation_angle) def translate_cube_x(slider): global cube_x, cube_y cube_x = slider.value
# Apply gravity to the scene. p.setGravity(0, 0, -10, physicsClientId=client) ############################################################################### # Set the Number of Dominoes for Simulation. number_of_dominoes = 10 # Base Plane Parameters base_size = np.array([number_of_dominoes * 2, number_of_dominoes * 2, 0.2]) base_color = np.array([1, 1, 1]) base_position = np.array([0, 0, -0.1]) base_orientation = np.array([0, 0, 0, 1]) # Render a BASE plane to support the Dominoes. base_actor = actor.box(centers=np.array([[0, 0, 0]]), directions=[0, 0, 0], scales=base_size, colors=base_color) # half of the actual size. base_coll = p.createCollisionShape(p.GEOM_BOX, halfExtents=base_size / 2) base = p.createMultiBody(baseCollisionShapeIndex=base_coll, basePosition=base_position, baseOrientation=base_orientation) p.changeDynamics(base, -1, lateralFriction=1, restitution=0.5) ############################################################################### # We define some global parameters of the Dominoes so that its easier for # us to tweak the simulation.
def test_manifest_standard(): # Test non-supported property test_actor = actor.text_3d('Test') npt.assert_warns(UserWarning, material.manifest_standard, test_actor) center = np.array([[0, 0, 0]]) # Test non-supported interpolation method test_actor = actor.square(center, directions=(1, 1, 1), colors=(0, 0, 1)) npt.assert_warns(UserWarning, material.manifest_standard, test_actor, interpolation='test') scene = window.Scene() # Setup scene test_actor = actor.box(center, directions=(1, 1, 1), colors=(0, 0, 1), scales=1) scene.add(test_actor) # scene.reset_camera() # window.show(scene) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 170]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 85]) / 1000 # TODO: check if camera affects this assert # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test ambient level material.manifest_standard(test_actor, ambient_level=1) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 255]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test ambient color material.manifest_standard(test_actor, ambient_level=.5, ambient_color=(1, 0, 0)) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 212]) / 1000 # TODO: check what affects this # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test diffuse level material.manifest_standard(test_actor, diffuse_level=.75) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 127]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 desired = np.array([0, 0, 128]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 64]) / 1000 # TODO: check what affects this # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test diffuse color material.manifest_standard(test_actor, diffuse_level=.5, diffuse_color=(1, 0, 0)) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 85]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 42]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular level material.manifest_standard(test_actor, specular_level=1) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([170, 170, 255]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([85, 85, 170]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular power material.manifest_standard(test_actor, specular_level=1, specular_power=5) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([34, 34, 204]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([1, 1, 86]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular color material.manifest_standard(test_actor, specular_level=1, specular_color=(1, 0, 0), specular_power=5) ss = window.snapshot(scene, size=(200, 200)) actual = ss[75, 100, :] / 1000 desired = np.array([34, 0, 170]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([1, 0, 85]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) scene.clear() # Reset scene # Special case: Contour from roi data = np.zeros((50, 50, 50)) data[20:30, 25, 25] = 1. data[25, 20:30, 25] = 1. test_actor = actor.contour_from_roi(data, color=np.array([1, 0, 1])) scene.add(test_actor) ss = window.snapshot(scene, size=(200, 200)) actual = ss[90, 110, :] / 1000 desired = np.array([253, 0, 253]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 0, 180]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) material.manifest_standard(test_actor) ss = window.snapshot(scene, size=(200, 200)) actual = ss[90, 110, :] / 1000 desired = np.array([253, 253, 253]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 180, 180]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) material.manifest_standard(test_actor, diffuse_color=(1, 0, 1)) ss = window.snapshot(scene, size=(200, 200)) actual = ss[90, 110, :] / 1000 desired = np.array([253, 0, 253]) / 1000 # TODO: check what affects the line below # npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 0, 180]) / 1000
l_particle = [ particle(colors=np.random.rand(1, 3), origin=origin, num_total_steps=num_total_steps, total_time=total_time, path_thickness=path_thickness) for _ in range(num_particles) ] scene.add(*l_particle) ############################################################################### # Creating a container (cube actor) inside which the particle(s) move around container_actor = actor.box(centers=np.array([[0, 0, 0]]), colors=(0.5, 0.9, 0.7, 0.4), scales=6) scene.add(container_actor) ############################################################################### # Initializing text box to display the name of the animation tb = ui.TextBlock2D(bold=True, position=(235, 40), color=(0, 0, 0)) tb.message = "Brownian Motion" scene.add(tb) ############################################################################### # The path of the particles exhibiting Brownian motion is plotted here def timer_callback(_obj, _event):
def test_manifest_standard(): # Test non-supported property test_actor = actor.text_3d('Test') npt.assert_warns(UserWarning, material.manifest_standard, test_actor) center = np.array([[0, 0, 0]]) # Test non-supported interpolation method test_actor = actor.square(center, directions=(1, 1, 1), colors=(0, 0, 1)) npt.assert_warns(UserWarning, material.manifest_standard, test_actor, interpolation='test') # Create tmp dir to save and query images with TemporaryDirectory() as out_dir: tmp_fname = os.path.join(out_dir, 'tmp_img.png') # Tmp image to test scene = window.Scene() # Setup scene test_actor = actor.box(center, directions=(1, 1, 1), colors=(0, 0, 1), scales=1) scene.add(test_actor) # Test basic actor window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 170]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 85]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test ambient level material.manifest_standard(test_actor, ambient_level=1) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 255]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test ambient color material.manifest_standard(test_actor, ambient_level=.5, ambient_color=(1, 0, 0)) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 212]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test diffuse level material.manifest_standard(test_actor, diffuse_level=.75) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 127]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 desired = np.array([0, 0, 128]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 64]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test diffuse color material.manifest_standard(test_actor, diffuse_level=.5, diffuse_color=(1, 0, 0)) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([0, 0, 85]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([0, 0, 42]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular level material.manifest_standard(test_actor, specular_level=1) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([170, 170, 255]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([85, 85, 170]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular power material.manifest_standard(test_actor, specular_level=1, specular_power=5) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([34, 34, 204]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([1, 1, 86]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) # Test specular color material.manifest_standard(test_actor, specular_level=1, specular_color=(1, 0, 0), specular_power=5) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[75, 100, :] / 1000 desired = np.array([34, 0, 170]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 125, :] / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[125, 75, :] / 1000 desired = np.array([1, 0, 85]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) scene.clear() # Reset scene # Special case: Contour from roi data = np.zeros((50, 50, 50)) data[20:30, 25, 25] = 1. data[25, 20:30, 25] = 1. test_actor = actor.contour_from_roi(data, color=np.array([1, 0, 1])) scene.add(test_actor) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[90, 110, :] / 1000 desired = np.array([253, 0, 253]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 0, 180]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) material.manifest_standard(test_actor) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[90, 110, :] / 1000 desired = np.array([253, 253, 253]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 180, 180]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) material.manifest_standard(test_actor, diffuse_color=(1, 0, 1)) window.record(scene, out_path=tmp_fname, size=(200, 200), reset_camera=True) npt.assert_equal(os.path.exists(tmp_fname), True) ss = load_image(tmp_fname) actual = ss[90, 110, :] / 1000 desired = np.array([253, 0, 253]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2) actual = ss[90, 60, :] / 1000 desired = np.array([180, 0, 180]) / 1000 npt.assert_array_almost_equal(actual, desired, decimal=2)