def intersectionPoint(self, pos, vel): posR = pos - self.origin # Calculate dot products and norms using the vector's component that is # perpendicular to the cylinder's axis (direction). # These are algebraically simplified versions for better performance posDotDir = vector3.dot(posR, self.direction) velDotDir = vector3.dot(vel, self.direction) posDotVel = vector3.dot(posR, vel) - posDotDir * velDotDir normPos2 = vector3.norm2(posR) - posDotDir**2 normVel2 = vector3.norm2(vel) - velDotDir**2 if normVel2 == 0: return math.inf A = posDotVel / normVel2 B = (normPos2 - self.R2) / normVel2 C = A**2 - B if C <= 0: return math.inf if B >= 0: if A >= 0: ds = math.inf else: ds = -sqrt(C) - A else: ds = sqrt(C) - A if ds <= 0: ds = math.inf return ds
def hit(self, ray_, t_min, t_max): assert isinstance(ray_, Ray) oc = ray_.origin - self.center a = dot(ray_.direction, ray_.direction) b = dot(oc, ray_.direction) c = dot(oc, oc) - self.radius * self.radius discriminant = b * b - a * c if discriminant > 0.0: temp = (-b - sqrt(b*b - a * c)) / a if t_min < temp < t_max: p = ray_.point_at_parameter(temp) rec = HitRecord(t=temp, p=p, normal=(p - self.center) / self.radius, material=self.material ) return True, rec temp = (-b + sqrt(b*b - a * c)) / a if t_min < temp < t_max: p = ray_.point_at_parameter(temp) rec = HitRecord(t=temp, p=p, normal=(p - self.center) / self.radius, material=self.material ) return True, rec return False, None
def hit(self, ray_, t_min, t_max): assert isinstance(ray_, Ray) oc = ray_.origin - self.center a = dot(ray_.direction, ray_.direction) b = dot(oc, ray_.direction) c = dot(oc, oc) - self.radius * self.radius discriminant = b * b - a * c if discriminant > 0.0: temp = (-b - sqrt(b * b - a * c)) / a if t_min < temp < t_max: p = ray_.point_at_parameter(temp) rec = HitRecord(t=temp, p=p, normal=(p - self.center) / self.radius, material=self.material) return True, rec temp = (-b + sqrt(b * b - a * c)) / a if t_min < temp < t_max: p = ray_.point_at_parameter(temp) rec = HitRecord(t=temp, p=p, normal=(p - self.center) / self.radius, material=self.material) return True, rec return False, None
def intersectionPoint(self, pos, vel): posR = pos - self.origin a = vector3.dot(vel, self.normalVector) b = vector3.dot(posR, self.normalVector) if a == 0: ds = math.inf else: ds = -b / a if ds <= 0: ds = math.inf return ds
def process(self, ray, ds): if self.constraint(ray.pos): normalVector = self.interphase.getNormalVector(ray.pos); if vector3.dot(ray.vel, normalVector) > 0: self.finalPower[ray.k] += ray.power; self.counter += 1; ray.loopOn = False;
def mt(v): r = v[0:3] t = v[3:6] x = np.linalg.norm(r) b = trig.cosox2(x) c = trig.sinox3(x) g = trig.specialFun1(x) h = trig.specialFun3(x) I = np.identity(3) return b*quat.skew(t) + c*(r*t.transpose() + t*r.transpose()) + v3.dot(r,t)*((c - b) * I + g*quat.skew(r) + h*r*r.transpose())
def intersectionPoint(self, pos, vel): posR = pos - self.origin posX = vector3.dot(posR, self.directionX) posY = vector3.dot(posR, self.directionY) velX = vector3.dot(vel, self.directionX) velY = vector3.dot(vel, self.directionY) if velX == 0: if velY == 0: return math.inf else: ds = (posX**2 * self.C - posY) / velY if ds <= 0: return math.inf else: return ds A = (posX * velX - velY / 2 / self.C) / velX**2 B = (posX**2 - posY / self.C) / velX**2 C = A**2 - B if C <= 0: return math.inf if B >= 0: if A >= 0: ds = math.inf else: ds = -sqrt(C) - A else: ds = sqrt(C) - A if ds <= 0: ds = math.inf return ds
def process(self, ray, ds): if self.constraint(ray.pos): normalVector = self.interphase.getNormalVector(ray.pos); # Get the reflected direction (for total or partial reflection) reflectedVel = ray.vel-2*vector3.projectNormal(ray.vel, normalVector); # Get the incidence angle cosTheta = vector3.dot(ray.vel, normalVector); # Choose the incident and refracted media based on the angle if cosTheta > 0: N1 = self.Nminus[ray.k]; N2 = self.Nplus[ray.k]; else: N1 = self.Nplus[ray.k]; N2 = self.Nminus[ray.k]; if N2 < N1 and cosTheta < sqrt(1-pow(N2/N1, 2)): # Total internal reflection ray.vel = reflectedVel; else: # Refraction or partial reflection # Get the refraction angle for calculating Fresnel reflection newCosTheta = copysign(sqrt(1-(1-cosTheta*cosTheta)*(N1/N2)**2), cosTheta); # Get the Fresnel coefficient for partial reflection fresnelR = basics.fresnelR(cosTheta, newCosTheta, N1, N2); if random() < fresnelR: # Partial reflection (random chance) ray.vel = reflectedVel; else: # Refraction (if no partial reflection) # Calculate refracted direction tangentVel = ray.vel-cosTheta*normalVector; newTangentVel = tangentVel*N1/N2; newNormalVel = newCosTheta*normalVector; ray.vel = newTangentVel+newNormalVel;
def getValuesFromPose(self, P): '''return the virtual values of the pots corresponding to the pose P''' vals = [] grads = [] for i, r, l, placement, attach_p in zip(range(3), self.rs, self.ls, self.placements, self.attach_ps): #first pot axis a = placement.rot * col([1, 0, 0]) #second pot axis b = placement.rot * col([0, 1, 0]) #string axis c = placement.rot * col([0, 0, 1]) #attach point on the joystick p_joystick = P * attach_p v = p_joystick - placement.trans va = v - dot(v, a)*a vb = v - dot(v, b)*b #angles of the pots alpha = math.atan2(dot(vb, a), dot(vb, c)) beta = math.atan2(dot(va, b), dot(va, c)) vals.append(alpha) vals.append(beta) #calculation of the derivatives dv = np.bmat([-P.rot.mat() * quat.skew(attach_p), P.rot.mat()]) dva = (np.eye(3) - a*a.T) * dv dvb = (np.eye(3) - b*b.T) * dv dalpha = (1/dot(vb,vb)) * (dot(vb,c) * a.T - dot(vb,a) * c.T) * dvb dbeta = (1/dot(va,va)) * (dot(va,c) * b.T - dot(va,b) * c.T) * dva grads.append(dalpha) grads.append(dbeta) return (col(vals), np.bmat([[grads]]))
def scatter(self, ray_in, hit_record): reflected = reflect(unit_vector(ray_in.direction), hit_record.normal) scattered = Ray(hit_record.p, reflected + random_in_unit_sphere() * self.fuzz) b = dot(scattered.direction, hit_record.normal) > 0.0 return b, self.albedo, scattered