def getRay(self, x,y): p = Point((float(x)/self.xmax)-0.5, (float(y)/self.ymax)-0.5, 0.0) r = Ray() r.o=self.viewpoint r.d=Vector(*(p-self.viewpoint).v) return r
class PointerRay(): def __init__(self, MANIPULATION_MANAGER, ID, SCENEGRAPH, NET_TRANS_NODE, PARENT_NODE, TRACKING_TRANSMITTER_OFFSET, POINTER_TRACKING_STATION, POINTER_DEVICE_STATION): self.tracking_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.tracking_sensor.Station.value = POINTER_TRACKING_STATION self.tracking_sensor.ReceiverOffset.value = avango.gua.make_identity_mat() self.tracking_sensor.TransmitterOffset.value = TRACKING_TRANSMITTER_OFFSET self.ray = Ray() self.ray.my_constructor(MANIPULATION_MANAGER, ID, SCENEGRAPH, NET_TRANS_NODE, PARENT_NODE, self.tracking_sensor.Matrix, POINTER_DEVICE_STATION)
class MouseRay(): def __init__(self, MANIPULATION_MANAGER, ID, SCENEGRAPH, NET_TRANS_NODE, PARENT_NODE, TRACKING_STATION, DEVICE_STATION): self.tracking_sensor = avango.daemon.nodes.DeviceSensor(DeviceService = avango.daemon.DeviceService()) self.tracking_sensor.Station.value = TRACKING_STATION self.tracking_sensor.ReceiverOffset.value = avango.gua.make_identity_mat() self.tracking_sensor.TransmitterOffset.value = avango.gua.make_identity_mat() self.mouse_mover = MouseMover() self.mouse_mover.my_constructor(self.tracking_sensor, PARENT_NODE.WorldTransform.value) self.ray = Ray() self.ray.my_constructor(MANIPULATION_MANAGER, ID, SCENEGRAPH, NET_TRANS_NODE, PARENT_NODE, self.mouse_mover.sf_output_mat, DEVICE_STATION)
def renderPixel(self, scene, row, col): #print() #print("Rendering ", row, col) primaryRay = Ray.PrimaryRay(self.eye, self.window[row][col], bouncesLeft=self.rayBounces) self.image[row][col] = primaryRay.getColor(scene)
def shadow(self, r_point, ray, obj, bbox): norm_vect = obj.calculate_norm_vect(r_point, ray) vect_to_light = self.point - r_point # Calculate distance to light source dist = np.linalg.norm(vect_to_light) # Calculate shadow ray towards light source shadow_ray = Ray(r_point, vect_to_light, None) # Compute closest object in shadow ray trajectory t, closest = bbox.find_closest(shadow_ray) #print('t', t) # Verify if object is in the way if (dist < t or t == -1): # Angle between shadow ray and object normal vector # TODO : Find out why np.pi- required angle = np.pi - math.acos( (norm_vect @ shadow_ray.vect) / (np.linalg.norm(norm_vect) * np.linalg.norm(shadow_ray.vect))) if (abs(angle) < np.pi / 2): # How much light is dimmed by the angle angle_factor = (np.pi / 2 - abs(angle)) / np.pi * 2 # How much light is dimmed by the distance dist_factor = 1 / (dist**2) # If light has been set to be equally bright at every distance if (self.brightness == -1): return angle_factor return dist_factor * angle_factor * self.brightness # Return no light return 0
def lookAt(self, screen, walls): self.rays = [] for i in range(0, 360, 1): self.rays.append(Ray.Ray1(self.pos[0], self.pos[1], np.deg2rad(i))) # self.rays.append(Ray.Ray1(self.pos[0], self.pos[1], np.pi/3)) # self.rays.append(Ray.Ray1(self.pos[0], self.pos[1], i)) # self.rays.append(Ray.Ray1(self.pos[0], self.pos[1], i)) for ray in self.rays: closest = 1000000000 closestpt = None for wall in walls: pt = ray.check(wall) if pt is not None: dist = np.linalg.norm(pt - self.pos) if dist < closest: closest = dist closestpt = pt if closestpt is not None: pygame.draw.line(screen, (255, 255, 255), self.pos, np.array(closestpt, int), 1)
def specularNonVerticalRayHorizonalSegment(intersection, rayLine): rayLineM = (rayLine.b[1] - rayLine.a[1]) / (rayLine.b[0] - rayLine.a[0]) incidentAngle = math.atan2(1, rayLineM) bouncedRayAngle = np.arctan2( (rayLine.b[1] - rayLine.a[1]), (rayLine.b[0] - rayLine.a[0])) + math.pi + (2 * incidentAngle) return Ray(intersection[0], intersection[1], bouncedRayAngle)
def snell(ray,sn,material1,material2) : n1 = material1.n n2 = material2.n # nr = n1/n2 # dp = pl.dot(ray.d,sn) # gam = ((nr*dp)**2-(n1/n2)+1)**0.5 - nr*dp # # new direction # d2 = ray.d*nr+gam*sn # d2 = d2/pl.linalg.norm(d2) # r = Ray(ray.p1,d2) nr = n1/n2 ct1 = -pl.linalg.dot(sn,ray.d) ct2 = pl.sqrt(1-(nr**2)*(1-ct1**2)) if ct1 < 0 : ct2 = -ct2 d2 = nr*ray.d+(nr*ct1-ct2)*sn r = Ray(ray.p1,d2) print 'snell> in\n',ray print 'snell> normal ',sn print 'snell> material 1',material1 print 'snell> material 2',material2 print 'snell> cos theta',ct1 print 'snell> cos theta',ct2 print 'snell> out',r return r
def compute_ray(m, k, i, j, eye, display, px_width, px_height): # Calculate the point on the display point = np.array([0,(i+0.5-m/2)*px_width,(j+0.5-k/2)*px_height]) # Calculate location of point in space real = point+display # Calculate vector in direction of eye to point vect = real-eye return Ray(eye, vect, None)
def specularNonVerticalRayVerticalSegment(intersection, rayLine, rayLineMDenominator): rayLineM = (rayLine.b[1] - rayLine.a[1]) / rayLineMDenominator normalM = 0 incidentAngle = math.atan2((normalM - rayLineM), 1 + (rayLineM * normalM)) bouncedRayAngle = np.arctan2( (rayLine.b[1] - rayLine.a[1]), (rayLine.b[0] - rayLine.a[0])) + math.pi + (2 * incidentAngle) return Ray(intersection[0], intersection[1], bouncedRayAngle)
def reflected_colour(self, comps, depth=5): if depth <= 0: return Tuple4.Colour(0, 0, 0) elif comps.object.material.reflective == 0: return Tuple4.Colour(0, 0, 0) else: reflect_ray = Ray.Ray(comps.over_point, comps.reflectv) colour = self.colour_at(reflect_ray, depth - 1) return colour * comps.object.material.reflective
def randomVerticalSegment(intersection, ray): if ray.pos[0] > intersection[0]: bouncedRayAngle = random.choice([ random.uniform(math.pi / 180, math.pi / 2), random.uniform(3 * math.pi / 2, 2 * math.pi) ]) else: bouncedRayAngle = random.uniform(91 * math.pi / 180, 3 * math.pi / 2) return Ray(intersection[0], intersection[1], bouncedRayAngle)
def specularVerticalRayNonHorizontalSegment(intersection, segmentMNumerator, segmentMDenominator, ray): segmentM = segmentMNumerator / segmentMDenominator normalM = -1 / segmentM incidentAngle = math.atan2(1, normalM) if ray.dir[1] > 0: bouncedRayAngle = (3 * math.pi / 2) - (2 * incidentAngle) else: bouncedRayAngle = (math.pi / 2) - (2 * incidentAngle) return Ray(intersection[0], intersection[1], bouncedRayAngle)
def create_rays(self, walls): self.rays = [] wall_q = self.create_heap(walls) qty = 1 if self.difficulty == 1: start_angle = (self.direction * 90) - (self.fov/2) for angle in range(0, int(self.fov)*qty): ray = Ray.Ray((self.location[0] + self.size/2, self.location[1] + self.size/2), self.size * (self.ray_size + 0.5), angle/qty + start_angle) ray.cast(wall_q) self.rays.append(ray)
def scatter(self, strike): """ See Material. basically just bounces some rays around smoothly and modulates. """ reflected = strike.ray.direction.unit().reflect(strike.normal) scattered = Ray(strike.point(), reflected) if (scattered.direction.dot(strike.normal) > 0): return Bounce(self.texture.value(0, 0, strike.point()), scattered) return Bounce(self.texture.value(0, 0, strike.point()))
def scatter(self, strike): """ See Material. basically just bounces some rays around randomly looking for more colour, and modulating. """ if (random.random() > self.emit): target = strike.point() + strike.normal + self.randomInSphere() scattered = Ray(strike.point(), target) return Bounce(self.texture.value(0, 0, strike.point()), scattered) else: return Bounce(self.texture.value(0, 0, strike.point()))
def is_shadowed(self, p, l): v = l.position - p distance = v.magnitude() direction = v.normalize() r = Ray.Ray(p, direction) intersections = self.intersections(r) h = intersections.hit() if h is not None and h.t < distance: return True else: return False
def randomDiagonalSegment(intersection, boundary, ray, m): b = boundary.b[1] - (boundary.b[0] * m) YL = (m * ray.pos[0]) + b DY = YL - ray.pos[1] LineAngle = np.arctan(m) if ((m > 0) and (DY < 0)) or ((m < 0) and (DY < 0)): bouncedRayAngle = random.uniform(LineAngle + (math.pi / 180), LineAngle + math.pi) else: bouncedRayAngle = random.uniform(LineAngle - (math.pi / 180), LineAngle - math.pi) return Ray(intersection[0], intersection[1], bouncedRayAngle)
def getReflected(self, ray, point): '''Returns the reflected ray of a ray that hits the plane that this triangle lies on ''' # R = 2P - L = 2(N(N dot L))-L # L = incoming * -1 # R = reflected # N = normal normal = self.getNormal() incoming = ray.d.normalize() * -1 #Incoming ray direction p = normal * normal.dot(incoming) reflected = (p * 2) - incoming #Reflected direction vector return Ray(point, reflected)
class Camera: xDim = 0 yDim = 0 ray = Ray.Ray((0, 0, 0), (0, 0, 0)) def __init__(self, xDim, yDim): self.xDim = xDim self.yDim = yDim def getPixel(self, x, y, spheres): return self.ray.cast((x, y, 0), (0, 0, 1), spheres)
def ray_for_pixel(self, px, py): # the offset from the edge of the canvas to the pixel's center xoffset = (px + 0.5) * self.pixel_size yoffset = (py + 0.5) * self.pixel_size # the untransformed coordinates of the pixel in world space. # (remember that the camera looks toward -z, so +x is to the *left*.) world_x = self.half_width - xoffset world_y = self.half_height - yoffset # using the camera matrix, transform the canvas point and the origin, # and then compute the ray's direction vector. # (remember that the canvas is at z=-1) pixel = self.transform.inverse() * Tuple4.Point(world_x, world_y, -1) origin = self.transform.inverse() * Tuple4.Point(0, 0, 0) direction = (pixel - origin).normalize() return Ray.Ray(origin, direction)
def __init__(self, diffuse=(0, 0, 1), specular=(1, 1, 1), phong=32, reflective=[0, 0, 0], vertex1=(.3, -.3, -1.4), vertex2=(0, .3, -1.1), vertex3=(-.3, -.3, -.8)): super().__init__(diffuse, specular, phong, reflective) self.vertex1 = vertex1 self.vertex2 = vertex2 self.vertex3 = vertex3 pn = np.cross(np.subtract(self.vertex3, self.vertex2), np.subtract(self.vertex1, self.vertex2)) pn = Ray.normalized(pn) self.plane_normal = pn
def calculatePower(x, y, wallsh, wallsv, precision, antenna): """calcule la puissance en un point""" ray = Ray(antenna[0], antenna[1], x + precision // 2, y + precision // 2) rays = getRayImage(antenna[0], antenna[1], wallsh, wallsv, ray) power = 0 dx = np.zeros(len(rays), dtype=np.float32) dy = np.zeros(len(rays), dtype=np.float32) nbWallsHc = np.zeros(len(rays), dtype=np.int8) nbWallsVc = np.zeros(len(rays), dtype=np.int8) nbWallsHb = np.zeros(len(rays), dtype=np.int8) nbWallsVb = np.zeros(len(rays), dtype=np.int8) En_carre = np.zeros(len(rays), dtype=np.float32) Z0 = 376.730313 Ra = 73 c = 299792458 lam = c / (27 * 10**9) he = -lam / math.pi factor = he**2 / 8 / Ra Gtx = 1.6977 Ptx = 0.1 # [W] for i in range(len(rays)): r = rays[i] if len(r.imagePoints) != 0: dx[i], dy[i] = r.receiverX - r.imagePoints[-1][ 0], r.receiverY - r.imagePoints[-1][1] for wall in r.walls: if wall.mat == 1: if wall.xDirection == 0: nbWallsVc[i] += 1 else: nbWallsHc[i] += 1 elif wall.mat == 0: if wall.xDirection == 0: nbWallsVb[i] += 1 else: nbWallsHb[i] += 1 else: dx[i], dy[i] = r.receiverX - r.originX, r.receiverY - r.originY En_carre[i] = reflexionPower(dx[i], dy[i], nbWallsHc[i], nbWallsVc[i], nbWallsHb[i], nbWallsVb[i]) En_carre[i] *= r.getTcoef(wallsh, wallsv) for e in En_carre: power += e print(En_carre) power *= factor * 60 * Gtx * Ptx return x, y, power, precision
def screenCoordToRay(window, x, y): width, height = glfw.get_window_size(window) matProjection = glGetDoublev(GL_PROJECTION_MATRIX).T matProjection = matProjection @ wld2cam[cameraIndex] # use @ for matrix mult. invMatProjection = np.linalg.inv(matProjection) # -1<=v.x<1 when 0<=x<width # -1<=v.y<1 when 0<=y<height vecAfterProjection = vector4( (float(x - 0)) / (float(width)) * 2.0 - 1.0, -1 * (((float(y - 0)) / float(height)) * 2.0 - 1.0), -10) vecBeforeProjection = position3(invMatProjection @ vecAfterProjection) rayOrigin = getTranslation(cam2wld[cameraIndex]) return Ray(rayOrigin, normalize(vecBeforeProjection - rayOrigin))
def shoot_ray(self, origin_row, origin_column): """ shoot_ray - shoots a ray from a given row and column if possible :param origin_row: :type origin_row: :param origin_column: :type origin_column: :return: Terminus Location (if it exists) or None :rtype: tuple(int, int) or None """ # get the the square object at row x column origin = self._board.get_board_square((origin_row, origin_column)) # check that it is a valid "edge" to send a ray from origin_check = origin.is_edge() # if it's not then return false if origin_check == False: return False # if we pass the origin check create shoot a new Ray.Ray object from row x column new_ray = Ray.Ray(origin_row, origin_column) # let the square we shot from know its an orign square origin.set_originating_ray(new_ray) # Deduct 1 from the score since we now have on exit point self.set_score(-1) # while the ray object has a direction (will be set to none when it reaches an endpoint) # send it to the helper function that will move it while new_ray.get_direction() != None: self.move_ray(new_ray) # if we hit an exit point (other than through reflection) deduct the point for that terminus = new_ray.get_terminal_location() # check the the terminal point is an edge (hitting an atom returns none as terminus) if terminus != None: # check that the terminus is not a reflection, which shouldn't be counted twice terminal_square = self._board.get_board_square(terminus) terminal_square.set_terminating_ray(new_ray) if terminus != (origin_row, origin_column): self.set_score(-1) return terminus
def exampleRays(self, d): r0 = Ray(self.placement.location, [0, 0, 1]) ryp = Ray(self.placement.location + pl.array([0, d, 0]), [0, 0, 1]) rypp = Ray(self.placement.location + pl.array([0, d / 2, 0]), [0, 0, 1]) ryn = Ray(self.placement.location + pl.array([0, -d, 0]), [0, 0, 1]) rynn = Ray(self.placement.location + pl.array([0, -d / 2, 0]), [0, 0, 1]) rxp = Ray(self.placement.location + pl.array([d, 0, 0]), [0, 0, 1]) rxn = Ray(self.placement.location + pl.array([-d, 0, 0]), [0, 0, 1]) self.append(r0) self.append(ryp) self.append(rypp) self.append(rynn) self.append(ryn) self.append(rxp) self.append(rxn)
def refractiveBouce(intersection, segment, ray, n1, n2): rayLine = Line(ray.pos[0], ray.pos[1], intersection[0], intersection[1]) segmentMNumerator = (segment.b[1] - segment.a[1]) rayLineMDenominator = (rayLine.b[0] - rayLine.a[0]) if segmentMNumerator == 0: if rayLineMDenominator == 0: refractedRayAngle = np.arccos(ray.dir[0]) else: rayLineM = (rayLine.b[1] - rayLine.a[1]) / (rayLine.b[0] - rayLine.a[0]) incidentAngle = math.atan2(1, rayLineM) if ray.pos[0] > intersection[0] and ray.pos[1] > intersection[1]: refractedRayAngle = ((3 * math.pi) / 2) - np.arccos( (n1 * np.cos(incidentAngle)) / n2) elif ray.pos[0] < intersection[0] and ray.pos[1] > intersection[1]: refractedRayAngle = ((3 * math.pi) / 2) + np.arccos( (n1 * np.cos(incidentAngle)) / n2) elif ray.pos[0] < intersection[0] and ray.pos[1] < intersection[1]: refractedRayAngle = (math.pi / 2) - np.arccos( (n1 * np.cos(incidentAngle)) / n2) else: refractedRayAngle = (math.pi / 2) + np.arccos( (n1 * np.cos(incidentAngle)) / n2) else: rayLineM = (rayLine.b[1] - rayLine.a[1]) / rayLineMDenominator normalM = 0 incidentAngle = math.atan2((normalM - rayLineM), 1 + (rayLineM * normalM)) if ray.pos[0] > intersection[0] and ray.pos[1] > intersection[1]: refractedRayAngle = math.pi + np.arccos( (n1 * np.cos(incidentAngle)) / n2) elif ray.pos[0] < intersection[0] and ray.pos[1] > intersection[1]: refractedRayAngle = (math.pi * 2) - np.arccos( (n1 * np.cos(incidentAngle)) / n2) elif ray.pos[0] < intersection[0] and ray.pos[1] < intersection[1]: refractedRayAngle = np.arccos((n1 * np.cos(incidentAngle)) / n2) else: refractedRayAngle = math.pi - np.arccos( (n1 * np.cos(incidentAngle)) / n2) return Ray(intersection[0], intersection[1], refractedRayAngle)
def lightDirectedBounce(intersection, boundary, ray, lightSources): sourcesIndexes = list(range(0, len(lightSources))) random.shuffle(sourcesIndexes) mDenominator = (boundary.b[0] - boundary.a[0]) if mDenominator != 0: mNumerator = (boundary.b[1] - boundary.a[1]) if mNumerator == 0: validSource = directedHorizontalSegment(intersection, ray, sourcesIndexes, lightSources) else: m = mNumerator / mDenominator validSource = directedDiagonalSegment(ray, sourcesIndexes, lightSources, m, boundary) else: validSource = directedVerticalSegment(intersection, ray, sourcesIndexes, lightSources) if validSource is not None: LineAngle = np.arctan2((validSource.pos[1] - intersection[1]), (validSource.pos[0] - intersection[0])) return Ray(intersection[0], intersection[1], LineAngle) else: return None
def reflect(ray,sn) : d2 = ray.d-2*pl.dot(ray.d,sn)*sn r = Ray(ray.p1,d2) return r
def __init__(self): self.pos = PVector(width / 2, height / 2) self.rays = [] for i in range(0, 360, 1): self.rays.append( Ray(self.pos, radians(i) ) )
def getRay(self, u, v): return Ray( self.origin, self.bottomLeft + self.horizontal * u + self.vertical * v - self.origin)
def casting3D(screen, screen_Size, walls, player_Pos, player_Size, look_ang, fov): #Define variables and other stuff. I should get rid off the number_ray variable as it is constant rays = [] number_rays = 200 ang_ray = look_ang - look_ang // 360 * 360 n = fov / number_rays for i in range(number_rays): rays.append( Ray.Ray(player_Pos[0] + (player_Size[0] / 2), player_Pos[1] + (player_Size[1] / 2), ang_ray + n * i, n * i, fov)) #Define variables and other stuff. intersec = [] pairs = [] good_rays = [] rendering_x = screen_Size[0] / 2 #La idea es tener un array así #[[(Tuple ray 1 cast 1),distance], # [(Tuple ray 1 cast 2), distancia] # ............................... # [(Tuple ray n cast n), distance]] # Y luego saco un solo array con las posiciones de interseccion for ray in rays: pairs = [] for wall in walls: if type(ray.cast(wall)) is np.ndarray: pairs.append([ray.cast(wall), ray.distance(), ray.cos]) else: pairs.append(["lul", screen_Size[0], "nope"]) #Verifica las distancias y pasa el par mas corto a la lista de intersecciones now = ["lul", screen_Size[0], 1] for pair in pairs: if pair[1] < now[1]: now = pair if now[0] != "lul": intersec.append(now[0]) good_rays.append(now) #3D cast #Render en la segunda parte del screen # debemos tomar cuantos pixeles va a tener de ancho cada ray # luego podemos hacer las lineas de ese numero de pixeles width_of_ray = int((screen_Size[0] / 2) // number_rays) p = 0 for ray in good_rays: p = 0 p = ray[1] * ray[2] wall_Height = screen_Size[1] / p * 15 if wall_Height > screen_Size[1]: wall_Height = screen_Size[1] / 2 b = 255 - 0.51 * p if b < 0: b = 1 for i in range(width_of_ray): rendering_x += 1 pg.draw.line(screen, (b, 0, 0), (rendering_x, (screen_Size[1] - wall_Height) / 2), (rendering_x, screen_Size[1] - (screen_Size[1] - wall_Height) / 2)) return intersec
import Scene, Object, Ray #def __init__(self, diffuse = (0, 0, 1), specular = (1, 1, 1), phong = 32, vertex1=(.3, -.3, -1.4), vertex2=(0, .3, -1.1), vertex3=(-.3, -.3, -.8) ): #triangle = Object.Triangle(vertex1=[-.2, .1, -.9], vertex2=[-.2, -.5, -.8], vertex3=[-.2, .1, -1.3], diffuse=[1,1,0], specular=[1,1,1], phong=4) triangle = Object.Triangle(vertex1=[-1, 1, -1], vertex2=[-1, -1, -1], vertex3=[1, 0, -2], diffuse=[1,1,0], specular=[1,1,1], phong=4) #def Ray(self, origin, direction, bouncesLeft = 0, shouldNormalize=True): #ray = Ray.Ray(origin=[0, 0, 0, 0], direction=[0, 0, -1, 0], shouldNormalize = True) #shadowRay origin: [-0.4946397718310972, 0.2473199359155486, -0.9302822977682621, 0] dest: [ 0.50536023 0.24731991 -0.9302822 0. ] #ray = Ray.Ray(origin=[-3, 0, -1, 0], direction=[ 1, 0, -1, 0. ], shouldNormalize = True) ray = Ray.Ray(origin=[0, 0, 0, 0], direction=[ 0, 0, -10, 0], shouldNormalize = True) print("rayOrigin: ", ray.origin, " rayDirection: ", ray.direction) intersection = triangle.rayIntersection(ray) print(intersection) ray = Ray.Ray(origin=[0, 0, -.5, 0], direction=[ 0, 0, -10, 0], shouldNormalize = True) print("rayOrigin: ", ray.origin, " rayDirection: ", ray.direction) intersection = triangle.rayIntersection(ray) print(intersection) ray = Ray.Ray(origin=[0, 0, -1, 0], direction=[ 0, 0, -10, 0], shouldNormalize = True) print("rayOrigin: ", ray.origin, " rayDirection: ", ray.direction) intersection = triangle.rayIntersection(ray) print(intersection) ray = Ray.Ray(origin=[0, 0, -1.4, 0], direction=[ 0, 0, -10, 0], shouldNormalize = True) print("rayOrigin: ", ray.origin, " rayDirection: ", ray.direction) intersection = triangle.rayIntersection(ray) print(intersection)