def getRay(self, line): """ Get the path of the light inside the stone. We suppose that the incident ray comes from the top of the stone.""" rays = [] # Search for the face on wich come the ray for face in self.getgTopFaces(): M = face['seg'].interceptLine(line) if M: break seg_in_ray = geo.Segment(line, y=[M[1],1]) rays.append(seg_in_ray) out_rays = face['seg'].getOutRays(line, 1, 1.9, M) old_face = face old_M = M rays.append(geo.Segment(out_rays['refracted'], y=[M[1], 1])) reflected_ray = out_rays['reflected'] for face in self.getgAllFacesButOne(old_face): M = face['seg'].interceptLine(reflected_ray) if M: break seg_ray = geo.Segment(reflected_ray, y=[old_M[1], M[1]]) rays.append(seg_ray) return rays
def __init__(self, plat_line, hauteur, culasse, ior): self.Faces = [] self.ior = ior table_line = geo.Line(0, [0, hauteur]) # interception entre plat et table inter_plat_table = table_line.intercept(plat_line) if not inter_plat_table: return table_hsize = max(inter_plat_table[0], 0) table = geo.Segment(table_line, x=[-table_hsize, table_hsize]) plat = geo.Segment(plat_line, x=[1, table_hsize]) self.addFace("table", table, True) self.addFace("platG", plat, True) self.addFace("platD", plat.getYSymetric(), True) # Culasse xstart = 1 for i,line in enumerate(culasse): if i+1 < len(culasse): nline = culasse[i+1] intercept = line.intercept(nline) xend = intercept[0] else: xend = 0 s = geo.Segment(line, x=[xstart, xend]) self.addFace("cplat" + str(i) + "G", s, False) self.addFace("cplat" + str(i) + "D", s.getYSymetric(), False) xstart = xend
def getLightPath(self, line): # Contains every light rays rays = [] ray = line prev_face = False prev_intercept = False for iteration in range(0,4): FacesGenerator = self.getgAllFacesButOne(prev_face) if iteration == 0: FacesGenerator = self.getgTopFaces() # For every face in the generator, search if the ray of # light intercept it for face in FacesGenerator: face_seg = face['seg'] intercept = face_seg.interceptLine(ray) if intercept: break if not intercept: # No face was found, nothing else to do break # We can delimit the previous ray and add it to the list if prev_intercept: rays.append({'inside': True, 'seg': geo.Segment(ray, y=[prev_intercept[1], intercept[1]]) }) else: rays.append({'inside': False, 'line': ray}) # Indice of refraction: First is the stone, then the air, # but for the first iteration n1, n2 = self.ior, 1 if iteration == 0: n1, n2 = 1, self.ior new_rays = face_seg.getOutRays(ray, n1, n2, intercept) if iteration == 0: inside_ray = new_rays['refracted'] outside_ray = new_rays['reflected'] else: inside_ray = new_rays['reflected'] outside_ray = new_rays['refracted'] # Put the outside ray in the list rays.append({'inside': False, 'line': outside_ray}) # the inside ray become the new ray and we start again ray = inside_ray prev_face = face prev_intercept = intercept return rays
def testGetOutRays(self): line = geo.Line(0, [0, 0]) segment = geo.Segment(line, x=[0, 2]) i1 = 1 for i in range(0, 50): i2 = 0.5 + random.random() angle = random.random() * 2 * math.pi ray = geo.Line(angle, [1, 0]) rays = segment.getOutRays(ray, i1, i2) incident_angle = math.fabs(angle - math.pi / 2) % math.pi incident_quarter = angle // (math.pi / 2) reflected = rays['reflected'] reflected_angle = math.fabs(reflected.angle - math.pi / 2) % math.pi reflected_quarter = reflected.angle // (math.pi / 2) self.assertAlmostEqual(incident_angle, reflected_angle, msg="Bad reflected angle") # Check that the reflected ray is on the right quarter of the trigo circle self.assertNotEqual( incident_quarter % 2, reflected_quarter % 2, msg="Reflected ray is the same as incident ray (%s)" % { 'angle': angle, 'i2': i2 }) if 'refracted' in rays: refracted = rays['refracted'] refracted_angle = math.fabs(refracted.angle - math.pi / 2) % math.pi refracted_quarter = refracted.angle // (math.pi / 2) self.assertAlmostEqual(i1 * math.sin(incident_angle), i2 * math.sin(refracted_angle)) self.assertTrue( math.fabs(refracted_quarter - incident_quarter) == 2, msg="Refracted ray is not on the right quarter (%r)" % { 'angle': angle, 'i2': i2, 'ray': ray, 'rays': rays })
def split(polygon, line): points = ([], []) segment_points = [] segment_idxs = [-1, -1] point_mappings = ([], []) last_point = polygon.points[-1] last_parity = point_parity(last_point, line) point_idx = 0 for point in polygon.points: parity = point_parity(point, line) if parity == 0: idx = 0 if last_parity == -1 else 1 segment_idxs[idx] = len(points[idx]) points[0].append(point) point_mappings[0].append(point_idx) points[1].append(point) point_mappings[1].append(point_idx) segment_points.append(point) else: idx = 0 if parity == -1 else 1 points[idx].append(point) point_mappings[idx].append(point_idx) last_parity = parity point_idx += 1 polygon0 = None polygon1 = None segment = None if len(segment_points) == 2: segment = geo.Segment(segment_points[0], segment_points[1]) if len(points[0]) > 2: polygon0 = geo.Polygon(points[0]) if len(points[1]) > 2: polygon1 = geo.Polygon(points[1]) return (polygon0, polygon1, segment, segment_idxs, point_mappings)
#!/bin/env python import geo from math import pi g = geo.Line(pi / 2, [1, 0]) h = geo.Line(0, [0, 1]) m = g.intercept(h) print "%s intercept %s in %s" % (g, h, m) g = geo.Line(pi / 4, [1, 0]) h = geo.Line(3 * pi / 4, [-1, 0]) m = g.intercept(h) print "%s intercept %s in %s" % (g, h, m) line = geo.Line(pi / 4, [0, 0]) segment = geo.Segment(line, x=[0, 1]) print segment line = geo.Line(pi / 2, [1, 0]) segment = geo.Segment(line, y=[0, 1]) print segment line = geo.Line(0, [0, 0]) segment = geo.Segment(line, x=[0, 2]) ray = geo.Line(pi / 2, [1, 0]) rays = segment.getOutRays(ray, 1, 1.9) print "Segment: %s, Ray: %s\n * Reflected: %s\n * Refracted: %s" % ( segment, ray, rays['reflected'], rays['refracted']) line = geo.Line(0, [0, 0]) segment = geo.Segment(line, x=[0, 2])