In [ ]:
from vpython import *

#This iteration projects rays from a sphere projecting to the surface of a larger spheroid.

spikeball = sphere(pos = vector(0, 0, 0), radius = 0.01, color = color.white)
r = curve(pos = [(0,0,0), (0,0,0)])

r.aa = curve(pos = [(0,0,0),(1, 0, 0)], color = color.yellow) #Set of rays along each axis (+/- x, +/- y, +/- z)
r.ab = curve(pos = [(0,0,0),(-1, 0, 0)], color = color.yellow)
r.ac = curve(pos = [(0,0,0),(0, 1, 0)], color = color.yellow)
r.ad = curve(pos = [(0,0,0),(0, -1, 0)], color = color.yellow)
r.ae = curve(pos = [(0,0,0),(0, 0, 1)], color = color.yellow)
r.af = curve(pos = [(0,0,0),(0, 0, -1)], color = color.yellow)

r.ba = curve(pos = [(0,0,0),(100/141.421, 100/141.421, 0)], color = color.yellow) #Set of rays in 2D planes of two coordinate axes
r.bb = curve(pos = [(0,0,0),(-100/141.421, 100/141.421, 0)], color = color.yellow)
r.bc = curve(pos = [(0,0,0),(100/141.421, -100/141.421, 0)], color = color.yellow)
r.bd = curve(pos = [(0,0,0),(-100/141.421, -100/141.421, 0)], color = color.yellow)
r.be = curve(pos = [(0,0,0),(100/141.421, 0, 100/141.421)], color = color.yellow)
r.bf = curve(pos = [(0,0,0),(-100/141.421, 0, 100/141.421)], color = color.yellow)
r.bg = curve(pos = [(0,0,0),(100/141.421, 0, -100/141.421)], color = color.yellow)
r.bh = curve(pos = [(0,0,0),(-100/141.421, 0, -100/141.421)], color = color.yellow)
r.bi = curve(pos = [(0,0,0),(0, 100/141.421, 100/141.421)], color = color.yellow)
r.bj = curve(pos = [(0,0,0),(0, -100/141.421, 100/141.421)], color = color.yellow)
r.bk = curve(pos = [(0,0,0),(0, 100/141.421, -100/141.421)], color = color.yellow)
r.bl = curve(pos = [(0,0,0),(0, -100/141.421, -100/141.421)], color = color.yellow)

r.ca = curve(pos = [(0,0,0), (100/173.205081,100/173.205081,100/173.205081)], color = color.yellow) #Set of rays along no explicit axis
r.cb = curve(pos = [(0,0,0), (-100/173.205081,100/173.205081,100/173.205081)], color = color.yellow)
r.cc = curve(pos = [(0,0,0), (100/173.205081,-100/173.205081,100/173.205081)], color = color.yellow)
r.cd = curve(pos = [(0,0,0), (100/173.205081,100/173.205081,-100/173.205081)], color = color.yellow)
r.ce = curve(pos = [(0,0,0), (-100/173.205081,-100/173.205081,100/173.205081)], color = color.yellow)
r.cf = curve(pos = [(0,0,0), (-100/173.205081,-100/173.205081,-100/173.205081)], color = color.yellow)
r.cg = curve(pos = [(0,0,0), (100/173.205081,-100/173.205081,-100/173.205081)], color = color.yellow)
r.ch = curve(pos = [(0,0,0), (-100/173.205081,100/173.205081,-100/173.205081)], color = color.yellow)

In [ ]:
from vpython import *

spikecube = sphere(pos = vector(0, 0, 0), radius = 0.01, color = color.white)
r = curve(pos = [(0,0,0), (0,0,0)])

r.aa = curve(pos = [(0,0,0),(1, 0, 0)], color = color.yellow) #Set of rays along each axis (+/- x, +/- y, +/- z)
r.ab = curve(pos = [(0,0,0),(-1, 0, 0)], color = color.yellow)
r.ac = curve(pos = [(0,0,0),(0, 1, 0)], color = color.yellow)
r.ad = curve(pos = [(0,0,0),(0, -1, 0)], color = color.yellow)
r.ae = curve(pos = [(0,0,0),(0, 0, 1)], color = color.yellow)
r.af = curve(pos = [(0,0,0),(0, 0, -1)], color = color.yellow)

r.ba = curve(pos = [(0,0,0),(1, 1, 0)], color = color.yellow) #Set of rays in 2D planes of two coordinate axes
r.bb = curve(pos = [(0,0,0),(-1, 1, 0)], color = color.yellow)
r.bc = curve(pos = [(0,0,0),(1, -1, 0)], color = color.yellow)
r.bd = curve(pos = [(0,0,0),(-1, 0, -1)], color = color.yellow)
r.be = curve(pos = [(0,0,0),(1, 0, 1)], color = color.yellow)
r.bf = curve(pos = [(0,0,0),(-1, 0, 1)], color = color.yellow)
r.bg = curve(pos = [(0,0,0),(1, 0, -1)], color = color.yellow)
r.bh = curve(pos = [(0,0,0),(-1, 0, -1)], color = color.yellow)
r.bi = curve(pos = [(0,0,0),(0, 1, 1)], color = color.yellow)
r.bj = curve(pos = [(0,0,0),(0, -1, 1)], color = color.yellow)
r.bk = curve(pos = [(0,0,0),(0, 1, -1)], color = color.yellow)
r.bl = curve(pos = [(0,0,0),(0, -1, -1)], color = color.yellow)

r.ca = curve(pos = [(0,0,0), (1,1,1)], color = color.yellow) #Set of rays along no explicit axis
r.cb = curve(pos = [(0,0,0), (-1,1,1)], color = color.yellow)
r.cc = curve(pos = [(0,0,0), (1,-1,1)], color = color.yellow)
r.cd = curve(pos = [(0,0,0), (1,1,-1)], color = color.yellow)
r.ce = curve(pos = [(0,0,0), (-1,-1,1)], color = color.yellow)
r.cf = curve(pos = [(0,0,0), (-1,-1,-1)], color = color.yellow)
r.cg = curve(pos = [(0,0,0), (1,-1,-1)], color = color.yellow)
r.ch = curve(pos = [(0,0,0), (-1,1,-1)], color = color.yellow)

In [ ]:
#Full Sphere of rays (point source)
from vpython import *
import numpy 


list_of_rays=[]  # Create an empty list named 'list_of_rays'
L=1  #Define a length for the rays

for i in numpy.arange(0,2*pi+0.1,.1):
    for k in numpy.arange(0,2*pi+0.1,.1):
    
        x=L*cos(k)*cos(i) #Prints vector with endpoint along a sphere
        y=L*cos(k)*sin(i) #Equation for a sphere in Spherical Coordinates
        z=L*sin(k)
    
        pointSource = sphere(pos = vector(0, 0, 0), radius = 0.01, color = color.white)
        rays = curve(pos=[vec(0,0,0),vec(x,y,z)], color=color.green)
  #  list_of_rays.append(new_curve)

In [ ]:
#This cell generates a beam of Parallel Rays (Uniform Step Size)
from vpython import *
import numpy 

L=10  #Define a length for the rays


for i in numpy.arange(0,1,.06):
        for k in numpy.arange(0,2*pi+0.1,.1):

            x1 = 0
            x2 = L
            y1 = i*sin(k)
            y2 = y1
            z1 = i*cos(k)
            z2 = z1
        
            beam = curve(pos=[vec(x1,y1,z1),vec(x2,y2,z2)], color=color.red)

In [ ]:
#This cell generates a beam of Parallel Rays (Step Size accounting for Gaussian distribution of beam density)
from vpython import *
import numpy 

L=10  #Define a length for the rays


for i in numpy.arange(0,1.15,.15):
    for j in numpy.arange(0,1+(1/e*e),pow(e,-2*i)): #Taking Gaussian Function for Radial Step 'i'
        for k in numpy.arange(0,2*pi+0.1,.1):

            x1 = 0
            x2 = L
            y1 = j*sin(k)
            y2 = y1
            z1 = j*cos(k)
            z2 = z1
        
            beam = curve(pos=[vec(x1,y1,z1),vec(x2,y2,z2)], color=color.red)

In [ ]:
#This cell generates a beam of Parallel Rays (Uniform Step Size)
from vpython import *
import numpy 

L=10  #Define a length for the rays




for i in numpy.arange(0,1,.06):
        for k in numpy.arange(0,2*pi+0.1,.1):
            
                x1 = 0
                x2 = L
                y1 = i*sin(k)
                y2 = y1
                z1 = i*cos(k)
                z2 = z1
                
              
                for x in numpy.arange(0,5,1):
                    beam = curve(pos=[vec(x1,y1,z1),vec(x2,y2,z2)], color=color.red)
                for x in numpy.arange(5,10,.1):
                    beam = curve(pos=[vec(x1,y1,z1),vec(x2,y2,z2)], color=color.green)

In [ ]:
#This cell generates a beam of Parallel Rays (Uniform Step Size) and changes the color as the beam passes x = 5
from vpython import *
import numpy 

L=10  #Define a length for the rays




for i in numpy.arange(0,1,.06):
        for k in numpy.arange(0,2*pi+0.1,.1):
            
                x1 = 0
                x2 = L
                y1 = i*sin(k)
                y2 = y1
                z1 = i*cos(k)
                z2 = z1
                
                beam = curve(pos=vec(x1,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.green)
                beam.append(pos=vec(x2,y2,z2), color=color.green)
                
#This is plotting a new curve that changes color from red to green at a prespecified point (x = 5).
#Can we make this change point variable?  or user input?

In [ ]:
#This cell generates a beam of Parallel Rays (Uniform Step Size) and changes the direction as the beam passes x = 5
from vpython import *
import numpy 

L=10  #Define a length for the rays


for i in numpy.arange(0,1,.06):
        for k in numpy.arange(0,2*pi+0.1,.1):
            
                x1 = 0
                x2 = L
                y1 = i*sin(k)
                y2 = y1
                z1 = i*cos(k)
                z2 = z1
                
                beam = curve(pos=vec(x1,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.red)
                beam.append(pos=vec(x2,y2,z2), color=color.red)
                
                #Define Vectors
                R = vector(1,0,0) #Vector along x-axis; just rays
                P = vector(-1,-1,-1) #Normal vector for a plane somewhere
                
                beam.append(pos=vec(x_o + dx, y_o + dy, z_o + dz) #Using (numpy.arcsin((1/(1.5))*sin(vector.diff_angle(R,P))))
                
#This is plotting a new curve that changes color from red to green at a prespecified point (x = 5).
#Can we make this change point variable?  or user input?

In [ ]:
from vpython import *
import numpy 

L=10  #Define a length for the rays




for i in numpy.arange(0,1,.6):
        for k in numpy.arange(0,2*pi+0.1,.1):
            
                x1 = 0
                x2 = L
                y1 = i*sin(k)
                y2 = y1
                z1 = i*cos(k)
                z2 = z1
                
                beam = curve(pos=vec(x1,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.red)
                beam.append(pos=vec(5,y1,z1), color=color.green)
                beam.append(pos=vec(x2,y2,z2), color=color.green)
                
#This is plotting a new curve that changes color from red to green at a prespecified point (x = 5).
#Can we make this change point variable?  or user input?

plane = box(pos=vector(15,0,0), length=20,height=5, width=10, up=vec(3,4,0), color=color.white,opacity=.5)
print(plane.axis)
print(plane.up)

In [ ]:
from vpython import *
import numpy

class ray():
    '''A light ray class'''
    def __init__(self,start_point,direction_vector,color):
        self.current_point=start_point
        self.direction_vector=direction_vector.norm()
        self.color=color
        self.length=10
        self.ray=curve(pos=self.current_point, color=self.color)
        
        #Draw all rays in Source
    def draw_ray(self):
        '''Draw a single light ray'''
        new_point=self.current_point+self.length*self.direction_vector.norm()
        self.current_point=new_point
        self.ray.append(new_point)
    
        #Define normal as normal vector to object
        #Using Snell's Law (numpy.arcsin((1/(1.5))*sin(vector.diff_angle(ray1,normal))))
    def new_direction(self,new_direction):
        '''Set a new direction for the ray'''
        self.direction_vector=new_direction                       #
        
        #Stop when encounters an object and then reset length to 10
    def new_length(self,new_length):
        '''Set a new length for the vector'''
        self.length=new_length
        
for i in numpy.arange(0,1,.05):
        for k in numpy.arange(0,2*pi+0.1,.05):
            
                direction_vector = vec(1,3,1).norm() #1, 3,and 1 are to be user-input, or calculated from existing ray
        
                beamDirection=direction_vector
                pos1=vec(0,0,0)
                
                dir_perp1=vec(beamDirection.y,-beamDirection.x,0)
                dir_perp2=beamDirection.cross(dir_perp1)
                
                perp1=ray(vec(0.5,1.5,0.5),dir_perp1,color.red)
                perp2=ray(vec(0.5,1.5,0.5),dir_perp2,color.green)
                
                perp1.draw_ray()
                perp2.draw_ray()
                
                new_start=pos1+i*(perp1.direction_vector*cos(k)+perp2.direction_vector*sin(k))
                
                ray1=ray(vec(new_start),direction_vector,color.blue)
                ray1.draw_ray()

In [ ]:
from vpython import *
import numpy

d = vec(1,3,1)
p = vec(0,1,-3)

beam1 = curve(pos=vec(0,0,0), color=color.red)
beam1.append (pos=vec(1,3,1))
beam2 = curve(pos=vec(0,0,0), color=color.green)
beam2.append(pos=vec(0,1,-3))
beam3 = curve(pos=vec(0,0,0), color=color.green)
beam3.append(pos=vec(1,0,-1))
beam4 = curve(pos=vec(0,0,0), color=color.green)
beam4.append(pos=vec(-3,1,0))
beam5 = curve(pos=vec(0,0,0), color=color.green)
beam5.append(pos=vec(-1,0,1))

In [4]:
from vpython import *
import numpy

scene = canvas()

#Classes
# A class is a template for an object
    #Ray class is a template for a ray
    #init: Set all of the variables for the beam
    #define methods

class ray():
    '''A light ray class'''
    def __init__(self,startPoint,directionVector,color):
        self.startPoint = startPoint
        self.currentPoint = startPoint
        self.directionVector = directionVector.norm()
        self.color = color
        self.length = 10
        self.ray = curve(pos=self.currentPoint, color=self.color)
        
        self.draw_ray()
        
        #Draw all rays in Source
    def draw_ray(self):
        '''Draw a single light ray'''
        newPoint = self.currentPoint + self.length*self.directionVector
        self.currentPoint = newPoint
        self.ray.append(newPoint)
        
        if newPoint.x > 5:
            self.currentPoint.x = 5
            thetaIncident = pi-diff_angle(self.directionVector,normal.directionVector)
            thetaRefracted = asin((n1/n2)*sin(thetaIncident))
            a1 = self.directionVector - normal.directionVector * (dot(self.directionVector,normal.directionVector))
            
            self.directionVector = (-1*cos(thetaRefracted)*normal.directionVector) + (sin(thetaRefracted)*a1.norm())
            
            newPoint = self.currentPoint + self.length*self.directionVector
            self.currentPoint = newPoint
            self.ray.append(newPoint)
            
        #Loop to check the position of newPoint.  If position is greater than 5, call Snell's Law
        #                                         and assign a new direction vector
    
        #Define normal as normal vector to object
        #Using Snell's Law (numpy.arcsin((1/(1.5))*sin(vector.diff_angle(ray1,normal))))
    def newDirection(self,newDirection):
        '''Set a new direction for the ray'''
        self.directionVector = newDirection                   
        
        #Stop when encounters an object and then reset length to 10
    def newLength(self,newLength):
        '''Set a new length for the vector'''
        self.length=newLength
        
class beam():
    '''A Beam Class'''
    def __init__(self, centerRay, width):
        self.centerRay = centerRay
        self.currentPoint = centerRay.currentPoint
        self.beamDirection = centerRay.directionVector
        self.width = width
        self.color = centerRay.color
        self.beam = []
     
    
        self.find_perp()
        self.draw_beam()

        
    def find_perp(self):
        '''Find two vectors perpendicular to the center ray'''
        if centerRay.directionVector.y==0 and centerRay.directionVector.x==0:
            self.perp1=vec(1,0,0)
        else:
            self.perp1 = norm(vec(centerRay.directionVector.y,-centerRay.directionVector.x,0))
        self.perp2 = norm(vec(centerRay.directionVector.cross(self.perp1)))
    def draw_beam(self):
        '''Draw a beam; lots of parallel rays'''
        for i in numpy.arange(0,self.width,.1): #CAN WE DEFINE A BEAM USING A FOR LOOP?
            for k in numpy.arange(0,2*pi+0.1,.1):
                self.newStart = centerRay.startPoint + i*(self.perp1*cos(k)+self.perp2*sin(k))
            
                beamRay = ray(self.newStart, self.beamDirection, self.color)
                        
                self.beam.append(beamRay)
        
class pointSource():
    def __init__(self, position):
        self.position = position
        self.color = centerRay.color
        self.pointSource = []
        self.source = sphere(pos=vec(centerRay.startPoint), radius=0.01, color=self.color)
        
        self.draw_pointSource()
    
    def draw_pointSource(self):
        '''Draw a point source'''
        self.source
        
        for i in numpy.arange(0,2*pi+0.1,(pi/36)):
            for k in numpy.arange(0,2*pi+0.1,(pi/36)):
                
                x = centerRay.length*(cos(k)*cos(i))
                y = centerRay.length*(cos(k)*sin(i))
                z = centerRay.length*(sin(k))
                
                pointSourceRay = ray(self.position, vec(x,y,z), self.color)
                
                self.pointSource.append(pointSourceRay)
                
#Class for planes
#As the ray is drawing itself, we need the ray to check its position against other possible objects
    #if it encouters another object, it need to call Snell's Law and give itself a new direction
normal = ray(vec(5,5,5),vec(-1,0,0),color.red) #y-z plane at x=5
n1 = 1.0 #Refractive index of air
n2 = 1.5 #Refractive index of glass

                        
centerRay = ray(vec(0,0,0), vec(1,1,1), color.green)
#beam1 = beam(centerRay, 2)
#pointSource1 = pointSource(centerRay.startPoint)

#Define normal and refractive index--> In box class (Material attribute?)
#normal = ray(centerRay.currentPoint,vec(-1,0,0),color.red) #y-z plane at x=5
n1 = 1.0 #Refractive index of air
n2 = 1.5 #Refractive index of glass

#print(centerRay.directionVector)
#print(normal.directionVector)

#REFRACT CODE
#thetaIncident = pi-diff_angle(centerRay.directionVector,normal.directionVector)
#thetaRefracted = asin((n1/n2)*sin(thetaIncident))
#a1 = centerRay.directionVector - normal.directionVector * (dot(centerRay.directionVector,normal.directionVector))
#print(a1)

#refractedRay = ray(centerRay.currentPoint, (-1*cos(thetaRefracted)*normal.directionVector) + (sin(thetaRefracted)*a1.norm()), color.yellow)
#refractedRay2 = ray(refractedRay.currentPoint, (-1*cos(thetaIncident)*normal.directionVector) + (sin(thetaIncident)*a1.norm()), color.green)

#glass = box(pos = ((refractedRay.startPoint + refractedRay.currentPoint)/2), axis = vec(1,0,0), up = vec(0,1,0), length = 8.33, width = 100, height = 100, opacity = 0.5)

class block():
    '''an optical obstacle class'''
    def __init__(self, position, axis, up, length, width, height, material):
        self.position = position
        self.axis = axis
        self.up = up
        self.material = material
        self.length = length
        self.width = width
        self.height = height
        if(self.material == "glass"):
             self.n = 1.5
            
        self.draw_block()
        
    def draw_block(self):
        self.shape = box(pos = self.position, axis = self.axis, up = self.up, length = self.length, width = self.width, height = self.height)
        
        self.normalFront = self.axis.norm()
        self.normalBack = -1 * self.axis.norm()
        self.normalTop = self.up.norm()
        self.normalBottom = -1 * self.up.norm()
        self.normalLSide = cross(self.axis, self.up)
        self.normalRSide = -1 * cross(self.axis, self.up)
        
    def check_boundaries(self, ray):
        b = ray.currentPoint - self.position
        b_old = ray.oldPoint - self.position

        
        if (abs(dot(rel_pos, self.normalBack)) < ((self.length)/2) and abs(dot(rel_old_pos, normalBack) > ((sel.flength)/2))
        
        frontCheck = dot(b,self.normalFront) - ((self.length)/2)
        backCheck = dot(b,self.normalBack) - ((self.length)/2)
        topCheck = dot(b,self.normalTop) - ((self.height)/2)
        bottomCheck = dot(b,self.normalBottom) - ((self.height)/2)
        lSideCheck = dot(b,self.normalLSide) - ((self.width)/2)
        rSideCheck = dot(b,self.normalRSide) - ((self.width)/2)
            
        frontCheck_old = dot(b_old,self.normalFront) - ((self.length)/2)
        backCheck_old = dot(b_old,self.normalBack) - ((self.length)/2)
        topCheck_old = dot(b_old,self.normalTop) - ((self.height)/2)
        bottomCheck_old = dot(b_old,self.normalBottom) - ((self.height)/2)
        lSideCheck_old = dot(,self.normalLSide) - ((self.width)/2)
        rSideCheck_old = dot(b_old,self.normalRSide) - ((self.width)/2)
                         
        if(frontCheck <= 0 and backCheck <= 0 and topCheck <= 0 and bottomCheck <= 0 and lSideCheck <= 0 and rSideCheck <= 0):
            print(1)
            
        
    
b1 = block(vec(0,0,0), vec(1,0,0), vec(0,1,0), 6, 3, 3, "glass")
print(b1.normalFront)
print(b1.normalBack)
print(b1.normalTop)
print(b1.normalBottom)
print(b1.normalLSide)
print(b1.normalRSide)
                         
ray1 = ray(vec(-7,0,0), vec(1,0,0), color.green)
                         
b1.check_boundaries(ray1)

ray2 = ray(vec(0,0,0), vec(0,0,1), color.blue)


<1.000000, 0.000000, 0.000000>
<-1.000000, -0.000000, -0.000000>
<0.000000, 1.000000, 0.000000>
<-0.000000, -1.000000, -0.000000>
<0.000000, 0.000000, 1.000000>
<-0.000000, -0.000000, -1.000000>
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-6397b4d4138d> in <module>()
    229 ray1 = ray(vec(-7,0,0), vec(1,0,0), color.green)
    230 
--> 231 b1.check_boundaries(ray1)
    232 
    233 ray2 = ray(vec(0,0,0), vec(0,0,1), color.blue)

<ipython-input-4-6397b4d4138d> in check_boundaries(self, ray)
    194     def check_boundaries(self, ray):
    195         b = ray.currentPoint - self.position
--> 196         b_old = ray.oldPoint - self.position
    197 
    198         frontCheck = dot(b,self.normalFront) - ((self.length)/2)

AttributeError: 'ray' object has no attribute 'oldPoint'

In [ ]:


In [ ]:


In [ ]:


In [ ]: