def __init__(self, origin, normal, resolutionX, resolutionY, pixelSizeInWorldCoords): Plane.__init__(self, origin, normal) self.resolutionX = resolutionX self.resolutionY = resolutionY self.pixelSizeInWorldCoords = pixelSizeInWorldCoords self.width = resolutionX * pixelSizeInWorldCoords self.height = resolutionY * pixelSizeInWorldCoords
def test_from_normal_and_point(): corners1 = [ Point(0.0, 0.0, 0.0), Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(0.0, 1.0, 0.0) ] center1 = Point(0.5, 0.5, 0.0) polygon1 = Polygon(corners1, center1) plane1 = Plane.from_normal_and_point(polygon1.plane().normal(), center1) assert polygon1.plane( ) == plane1 # tests the reduced normal form coefficients. corners2 = [ Point(0.0, 0.0, 0.0), Point(0.0, 1.0, 0.0), Point(0.0, 1.0, 1.0), Point(0.0, 0.0, 1.0) ] center2 = Point(0.0, 0.5, 0.5) polygon2 = Polygon(corners2, center2) plane2 = Plane.from_normal_and_point(polygon2.plane().normal(), center2) assert polygon2.plane() == plane2 corners4 = [ Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(1.0, 1.0, 1.0), Point(1.0, 0.0, 1.0) ] center4 = Point(1.0, 0.5, 0.5) polygon4 = Polygon(corners4, center4) plane4 = Plane.from_normal_and_point(polygon4.plane().normal(), center4) assert polygon4.plane() == plane4
def test_on_interior_side(a, b, c, d): plane = Plane.from_normal(Vector(1.0, 0.0, 0.0)) assert b.on_interior_side_of(plane) == +1 # Interior side assert c.on_interior_side_of(plane) == 0 # In plane assert d.on_interior_side_of(plane) == -1 # Exterior side points = [ Point(0.0, 0.0, -1.0), Point(0.0, 1.0, -1.0), Point(0.0, 1.0, 0.0), Point(0.0, 0.0, 0.0) ] plane = Plane.from_points(points) assert b.on_interior_side_of(plane) == +1 # Interior side assert c.on_interior_side_of(plane) == 0 # In plane assert d.on_interior_side_of(plane) == -1 # Exterior side
def test_intersection(): plane = Plane(0.0, 0.0, 1.0, -0.9) a = Point(0.5, 0.5, -0.9) b = Point(0.0, 0.0, 0.0) assert plane.intersection(a, b) == Point(-0.5, -0.5, 0.9) points = [Point(0.5, 0.0, 0.0), Point(0.5, 1.0, 0.0), Point(0.5, 1.0, 1.0), Point(0.5, 0.1, 1.0)] polygon = Polygon(points, Point(0.5, 0.5, 0.5)) source = Point(0.5, 0.5, 0.5) mirror = source.mirror_with(Plane.from_normal_and_point(Vector(1.0, 0.0, 0.0), Point(1.0, 0.5, 0.5))) intersection = polygon.plane().intersection(mirror, Point(1.0, 0.0, 0.0)) assert intersection == Point(0.5, -0.5, -0.5)
def __init__(self): self.objects = [Plane(Point3D(0, -.5, 0), Vector3D(0, 1, 0), color=Color(1, 1, 1)), Sphere(Point3D(0, 0, -1.0), 0.1, color=Color(1.0, 0, 0))] self.lights = [UniformPointLight(Point3D(-.5, 0, -1), Color(100, 100, 100))]
def make_conic(R, K, z_offset, material=None, reverse_normal=False): """ See https://en.wikipedia.org/wiki/Conic_constant r^2 - 2Rz + (K+1)z^2 = 0 Be careful about the sign convention for radius of curvature. We follow the convention in https://en.wikipedia.org/wiki/Conic_constant but this is opposite the convention in https://en.wikipedia.org/wiki/Lens#Lensmaker's_equation . Args: R: radius of curvature; use R > 0 for concave "up" (direction of positive z-axis) while R < 0 is concave "down" K: conic constant; should be < -1 for hyperboloids, -1 for paraboloids, > -1 for ellipses (including 0 for spheres). The relationship with eccentricity e is K = -e^2 (when K <= 0). z_offset: z-coordinate where the surface intersects z-axis material: mostly self explanatory; None means reflector reverse_normal: If true, surface points in direction of negative z-axis rather than positive z-axis """ M = np.diag([1, 1, (K + 1), 0]) M[2, 3] = -R M[3, 2] = M[2, 3] # For either sign of R, we want the convention that gradient points up at origin. # That gradient is (0,0,-R). # When R < 0, we already have that. # For R > 0, we need to negate M to get that. if R > 0: M *= -1 if reverse_normal: M *= -1 quad = Quadric(M) geometry = quad.untransform(translation3f(0, 0, -z_offset)) if R > 0: # We want to keep the top sheet. # TODO: Let clip_z be halfway between the two foci. clip_z = z_offset - 1e-6 clip = Plane(make_bound_vector(point(0, 0, clip_z), vector(0, 0, -1))) else: clip_z = z_offset + 1e-6 clip = Plane(make_bound_vector(point(0, 0, clip_z), vector(0, 0, 1))) return SubElement(geometry, clip, material=material)
def test_pickle(): a = Plane(0.0, 0.0, 1.0, -0.9) with tempfile.TemporaryDirectory() as tmpdirname: with open('obj.pickle', mode='w+b') as f: pickle.dump(a, f) with open('obj.pickle', mode='r+b') as f: a2 = pickle.load(f) assert a2 == a
def test_from_normal_and_point(): corners1 = [ Point(0.0, 0.0, 0.0), Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(0.0, 1.0, 0.0) ] center1 = Point(0.5, 0.5, 0.0) polygon1 = Polygon(corners1, center1) plane1 = Plane.from_normal_and_point(polygon1.plane().normal(), center1) assert polygon1.plane() == plane1 # tests the reduced normal form coefficients. corners2 = [ Point(0.0, 0.0, 0.0), Point(0.0, 1.0, 0.0), Point(0.0, 1.0, 1.0), Point(0.0, 0.0, 1.0) ] center2 = Point(0.0, 0.5, 0.5) polygon2 = Polygon(corners2, center2) plane2 = Plane.from_normal_and_point(polygon2.plane().normal(), center2) assert polygon2.plane() == plane2 corners4 = [ Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(1.0, 1.0, 1.0), Point(1.0, 0.0, 1.0) ] center4 = Point(1.0, 0.5, 0.5) polygon4 = Polygon(corners4, center4) plane4 = Plane.from_normal_and_point(polygon4.plane().normal(), center4) assert polygon4.plane() == plane4
def __init__(self, start, p2, end, color=(0, 1, 0, .3), num_points=50): plane = Plane(start, p2, end) pr1 = plane.project(start) pr2 = plane.project(p2) pr3 = plane.project(end) circle = Circle(pr1, pr2, pr3) radian_len = circle.chord_angle(pr1.distance(pr3)) increment = radian_len / num_points diff = pr1 - circle.center offset = np.arctan(diff.y / diff.x) # the range of arcsin is from -90 to 90 so (or radians but that's harder to type) if diff.x < 0: offset += np.pi / 2 else: offset -= np.pi / 2 points3d = [] for p in range(num_points): radian = increment * p - offset point = circle.center + Vector( np.sin(radian) * circle.radius, np.cos(radian) * circle.radius) points3d.append(plane.unproject(point)) points3d.append(end) super(Arc, self).__init__(pos=np.array(points3d), color=color, width=2, antialias=True, mode='line_strip')
def test_intersection(): plane = Plane(0.0, 0.0, 1.0, -0.9) a = Point(0.5, 0.5, -0.9) b = Point(0.0, 0.0, 0.0) assert plane.intersection(a, b) == Point(-0.5, -0.5, 0.9) points = [ Point(0.5, 0.0, 0.0), Point(0.5, 1.0, 0.0), Point(0.5, 1.0, 1.0), Point(0.5, 0.1, 1.0) ] polygon = Polygon(points, Point(0.5, 0.5, 0.5)) source = Point(0.5, 0.5, 0.5) mirror = source.mirror_with( Plane.from_normal_and_point(Vector(1.0, 0.0, 0.0), Point(1.0, 0.5, 0.5))) intersection = polygon.plane().intersection(mirror, Point(1.0, 0.0, 0.0)) assert intersection == Point(0.5, -0.5, -0.5)
from geometry import create_cube, clip, Plane from unfolding import unfold import svg cube = create_cube() plane1 = Plane(0,0,1, 1/3) plane2 = Plane(0,0,1,-1/3) ph12 = clip(cube,plane2) ph1 = clip(ph12,plane1) ph2 = clip(ph12,-plane1) ph3 = clip(cube,-plane2) svg.write_unfolded_faces('test2a.svg', unfold(ph1)) svg.write_unfolded_faces('test2b.svg', unfold(ph2)) svg.write_unfolded_faces('test2c.svg', unfold(ph3))
if out != b'0\r\n': print(out) if out == b'': raise TimeoutError('Arduino serial not respond') def __del__(self): self._pos = [0, 0, 0] self._serial.close() if __name__ == "__main__": import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from geometry import Ray, Plane, Intersection, Reflection plt.ion() fig = plt.figure() ax = fig.gca(projection='3d') ax.set_xlim(-100, 100) ax.set_ylim(-90, 90) ax.set_zlim(0, 600) p1, p2 = Plane(ax=ax), Plane(ax=ax) p1.z, p2.z = 200, 400 p1.phi, p2.phi = 0, 0 c = Chanosat_Driver(ax=ax) r1 = Reflection(c, p1) a = Intersection(c, p1)
#!/usr/bin/python from geometry import Plane, Sphere, Triangle, Cube from scene import Screen, Scene from tracer import SimpleRayTracer, SimpleShadowRayTracer, ShadingShadowRayTracer, RecursiveRayTracer, PathTracer from material import Material, Color from window import Window if __name__ == "__main__": p1 = Plane([0, 5, 0], [0, -1, 0], Material(Color(255, 0, 0), 1, 0, 0.1)) p2 = Plane([0, -5, 0], [0, 1, 0], Material(Color(0, 255, 0), 1, 0, 0.1)) p3 = Plane([5, 0, 0], [-1, 0, 0], Material(Color(0, 0, 255), 1, 0, 0.1)) p4 = Plane([-5, 0, 0], [1, 0, 0], Material(Color(255, 255, 0), 1, 0, 0.1)) p5 = Plane([0, 0, 5], [0, 0, -1], Material(Color(255, 0, 255), 1, 0, 0.1)) p6 = Plane([0, 0, -5], [0, 0, 1], Material(Color(0, 255, 255), 1, 0, 0.1)) s1 = Sphere([0, 3, 2], 2, Material(Color(100, 100, 100), 1, 0, 0.1, refractive=False, n=1.52)) s2 = Sphere([4, 2, 1], 0.5, Material(Color(100, 100, 100), 1, 0, 0.1, refractive=False, n=1.52)) s3 = Sphere([-3, 2, 1], 1,
from geometry import Point3, create_cube, clip, Plane from unfolding import unfold import svg import math m = 5 cube = create_cube() rest = cube pieces = [] for i in range(m): theta = math.pi/6 * (1-2*i/(m-1)) u = Point3(math.sin(theta),0,math.cos(theta)) plane = Plane(u.x,u.y,u.z, -2*u.x) pieces.append(clip(rest, -plane)) rest = clip(rest, plane) pieces.append(rest) for i,piece in enumerate(pieces): svg.write_unfolded_faces(f"test3-{i+1}.svg", unfold(piece))
from geometry import create_cube, clip, Plane from unfolding import unfold import svg cube = create_cube() cube.assert_integrity() plane = Plane(1,1,0,0) ph = clip(cube,plane) ph.assert_integrity() svg.write_unfolded_faces('test5.svg', unfold(ph))
def __init__(self, filename="scene.json"): self.lights = [] self.objects = [] # read in the json with open(filename, "r") as json_file: scene = json.load(json_file) for light in scene['scene']['lights']: l = Light(origin=light['origin'], radius=light['radius'], brightness=light['brightness'], color=light['color']) self.lights.append(l) self.objects.append(l) for object in scene['scene']['objects']: texture = None scale = 1.0 if 'texture' in object: texture = object['texture'] if 'scale' in object: scale = object['scale'] if (object['shape'] == "Sphere"): self.objects.append( Sphere(origin=object['origin'], radius=object['radius'], diffuse=object['diffuse'], reflection=object['reflection'], shiny=object['shiny'], k=object['k'], refraction=object['refraction'], index=object['index'], color=object['color'], texture=texture, uv=object['uv'])) elif (object['shape'] == "Skybox"): self.objects.append( Skybox(origin=object['origin'], radius=object['radius'], diffuse=object['diffuse'], reflection=object['reflection'], shiny=object['shiny'], k=object['k'], refraction=object['refraction'], index=object['index'], color=object['color'], texture=texture, uv=object['uv'])) elif (object['shape'] == "Plane"): self.objects.append( Plane.Plane(origin=object['origin'], normal=object['normal'], diffuse=object['diffuse'], reflection=object['reflection'], refraction=object['refraction'], index=object['index'], shiny=object['shiny'], k=object['k'], color=object['color'], texture=texture, scale=scale)) elif (object['shape'] == "Triangle"): self.objects.append( Triangle.Triangle(v0=object['v0'], v1=object['v1'], v2=object['v2'], diffuse=object['diffuse'], reflection=object['reflection'], refraction=object['refraction'], index=object['index'], shiny=object['shiny'], k=object['k'], color0=object['color0'], color1=object['color1'], color2=object['color2'])) camera = scene['scene']['camera'] self.camera = Camera(origin=camera['origin'], target=camera['target'], length=camera['length'], aperture=camera['aperture'], samples=camera['samples']) self.ambient = np.array(scene['scene']['ambient']) self.background = np.array(scene['scene']['background'])
from unfolding import unfold import svg import math m = 5 cube = create_cube() rest = cube pieces = [] phi = math.pi / 4 cs_phi = math.cos(phi) sn_phi = math.sin(phi) for i in range(m): theta = math.pi / 6 * (1 - 2 * i / (m - 1)) u = Point3(math.sin(theta), 0, math.cos(theta)) u.x, u.y = cs_phi * u.x, sn_phi * u.x plane = Plane(u.x, u.y, u.z, -2 * (u.x + u.y)) pieces.append(clip(rest, -plane)) rest = clip(rest, plane) pieces.append(rest) for i, piece in enumerate(pieces): svg.write_unfolded_faces(f"test4-{i+1}.svg", unfold(piece))
def __get_bragg_planes(zone_points): """Return the Bragg planes.""" for points in zone_points: middle_points = map(lambda point: point * 0.5, points) for middle_point in middle_points: yield Plane(middle_point, Vector3D(tuple(middle_point)))