Esempio n. 1
0
    def intersects(self, r):
        ''' ???
            :param Ray r:
            :returns: ?, point, normal
            :rtype: float, Vector3D, Vector3D
        '''
        y = r.start - self._center
        c = vector.dot(y, y) - self._radius * self._radius
        b = vector.dot(r.direction, y)
        if b * b - c < 0:
            return float('inf'), None, None
        t1 = -b + math.sqrt(b * b - c)
        t2 = -b - math.sqrt(b * b - c)

        if t1 < 0:
            return float('inf'), None, None
        else:
            if t2 < 0:
                point = r.start + r.direction * t1
                normal = (point - self._center).normalized
                if t1 < r.t_max:
                    return t1, point, normal
                else:
                    return float('inf'), None, None
            else:
                point = r.start + r.direction * t2
                normal = (point - self._center).normalized
                if t2 < r.t_max:
                    return t2, point, normal
                else:
                    return float('inf'), None, None
Esempio n. 2
0
    def calculate_normal(self, b1, b2):
        """
        Calculates the normal of b1 with respect to b2
        """
        normal_x = 0.0
        normal_y = 0.0

        # Difference between body centers
        center_dir = vector.normalize(vector.sub(b1.rect.center(), b2.rect.center()))

        cos_threshold = b2.rect.w / math.sqrt(math.pow(b2.rect.h, 2) + math.pow(b2.rect.w, 2))
        if vector.dot(center_dir, vector.Vector2(1, 0)) >= cos_threshold:
            # b1 is at the right side of b2
            normal_x = 1.0
        elif vector.dot(center_dir, vector.Vector2(-1, 0)) >= cos_threshold:
            # b1 is at the left side of b2
            normal_x = -1.0
        elif vector.dot(center_dir, vector.Vector2(0, -1)) >= math.cos(math.pi * 0.5 - math.acos(cos_threshold)):
            # b1 is above b2
            normal_y = -1.0
        else:
            # b1 is below b2
            normal_y = 1.0

        return vector.Vector2(normal_x, normal_y)
Esempio n. 3
0
    def lighting(self, lights, camera, transform):
        temp_color = Vector3(0, 0, 0)
        supern = (self.normal * transform).normalized()
        for l in range(len(lights)):
            center = self.center * transform
            amb = self.scene.pairwise_mult(self.md[self.material]["amb"])
            temp_color += amb
            n = (lights[l].pos - center).normalized()
            o = vector.dot(n, supern)
            if o < 0:
                pass
            else:

                r = 2 * o * supern - n
                i = VectorN(camera.pos.x, camera.pos.y, camera.pos.z, 1)
                v = (i - center).normalized()
                m = vector.dot(v, r)
                diff_c = o * lights[l].diff.pairwise_mult(
                    self.md[self.material]["diff"])
                if m < 0:
                    spec_c = vector.Vector3(0, 0, 0)
                else:
                    spec_c = m ** self.md[self.material]["hard"] * \
                            (lights[l].spec.pairwise_mult(self.md[self.material]["spec"]))
                temp_color += spec_c + diff_c
        return temp_color.clamp()
    def G_GGX_Isotropic(parameters: Tensor, normals: Tensor,
                        directions: Tensor, halfways: Tensor) -> Tensor:
        '''
        Evaluates the isotropic GGX shadow-masking G1 function for the provided halfway and (incident or outbound) directions
        using the given parameters.  See https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf for more details.

        Args:
            parameters: Tensor [B, R, C, 4] of α and normal parameters.
            normals: Tensor [B, R, C, D, 3] of surface normals.
            directions: Tensor [B, R, C, D, 3] of (incident or outbound) directions.
            halfways: Tensor [B, R, C, D, 3] of halfway directions.

        Returns:
            Tensor [B, R, C, D, 3] of G1 visibility values for each (incident or outbound) direction.
        '''
        assert parameters.size(
            3
        ) == 1, 'Isotropic GGX shadow-masking G1 function must have 1 value for each spatial parameter.'
        alphas = torch.unsqueeze(parameters, dim=3)
        visible = torch.sign(
            vector.dot(directions, halfways) *
            vector.dot(directions, normals)) == 1
        zeniths = vector.dot(directions, normals)
        return visible / (zeniths + torch.sqrt(alphas**2 +
                                               (1 - alphas**2) * zeniths**2))
Esempio n. 5
0
def rr_int(p1, v1, p2, v2):
    """Intersect ray though p1 direction v1 with ray through p2 direction v2.
       Returns a list of zero or one solutions
    """
    diag_print("rr_int "+str(p1)+str(v1)+str(p2)+str(v2),"intersections")
    s = ll_int(p1,v1,p2,v2)
    if len(s) > 0 and tol_gte(vector.dot(s[0]-p2,v2), 0) and tol_gte(vector.dot(s[0]-p1,v1),0):
        return s
    else:
        return []
Esempio n. 6
0
def test_perp_3d():
    for i in range(10):
        u = normalised(vector.randvec(3))
        v, w = perp_3d(u)
        print u, vector.norm(u)
        print v, vector.norm(v)
        print w, vector.norm(w)
        print tol_eq(vector.dot(u, v), 0.0)
        print tol_eq(vector.dot(v, w), 0.0)
        print tol_eq(vector.dot(w, u), 0.0)
Esempio n. 7
0
def test_perp_3d():
    for i in range(10):
        u = normalised(vector.randvec(3))
        v,w = perp_3d(u)
        print u, vector.norm(u)
        print v, vector.norm(v)
        print w, vector.norm(w)
        print tol_eq(vector.dot(u,v),0.0) 
        print tol_eq(vector.dot(v,w),0.0) 
        print tol_eq(vector.dot(w,u),0.0) 
Esempio n. 8
0
def dir_from_segment(point, a, b):
    if dot(b - a, point - a) <= 0:
        return normalize(point - a)
    if dot(a - b, point - b) <= 0:
        return normalize(point - b)
    normal = normalize(b - a)
    normal = Vector(-normal.y, normal.x)
    if dot(normal, point - a) < 0:
        normal = -normal
    assert(distance_to_segment(point, a, b) < distance_to_segment(point + normal, a, b))
    return normal
Esempio n. 9
0
def rr_int(p1, v1, p2, v2):
    """Intersect ray though p1 direction v1 with ray through p2 direction v2.
       Returns a list of zero or one solutions
    """
    diag_print("rr_int " + str(p1) + str(v1) + str(p2) + str(v2),
               "intersections")
    s = ll_int(p1, v1, p2, v2)
    if len(s) > 0 and tol_gte(vector.dot(s[0] - p2, v2), 0) and tol_gte(
            vector.dot(s[0] - p1, v1), 0):
        return s
    else:
        return []
Esempio n. 10
0
def dir_from_segment(point, a, b):
    if dot(b - a, point - a) <= 0:
        return normalize(point - a)
    if dot(a - b, point - b) <= 0:
        return normalize(point - b)
    normal = normalize(b - a)
    normal = Vector(-normal.y, normal.x)
    if dot(normal, point - a) < 0:
        normal = -normal
    assert (distance_to_segment(point, a, b) < distance_to_segment(
        point + normal, a, b))
    return normal
Esempio n. 11
0
 def intersect(self, ray):
     v1 = ray.orig - self.a
     v2 = self.b - self.a
     v3 = Vector(-ray.dir.y, ray.dir.x)
     if dot(v2, v3) == 0:
         return None
     ts = dot(v1, v3) / dot(v2, v3)
     tr = cross(v2, v1) / dot(v2, v3)
     if tr >= 0.0 and 0.0 <= ts <= 1.0:
         return self.a + v2 * ts
     else:
         return None
Esempio n. 12
0
 def intersect(self, ray):
     v1 = ray.orig - self.a
     v2 = self.b - self.a
     v3 = Vector(-ray.dir.y, ray.dir.x)
     if dot(v2, v3) == 0:
         return None
     ts = dot(v1, v3) / dot(v2, v3)
     tr = cross(v2, v1) / dot(v2, v3)
     if tr >= 0.0 and 0.0 <= ts <= 1.0:
         return self.a + v2 * ts
     else:
         return None
Esempio n. 13
0
 def rayTest(self, R):
     """Returns a list of sorted Raycollisions or none if its empty."""
     Q = vector.dot(R.Dhat, self.norm)
     if Q != 0:
         t = (self.distance - vector.dot(R.origin, self.norm)) / Q
         if t < 0:
             return []
         else:
             p = R.getPoint(t)
             return [Raycollision(R, self, t, p, self.norm)]
     else:
         return []
Esempio n. 14
0
    def f_matrix2fit(beta, x, efit):
        b = numpy.matrix(lmap(lambda a, b: a - b, x[:3], beta[:3]))
        r = numpy.matrix([[1, efit[0], efit[1]], [efit[2], beta[4], efit[3]],
                          [efit[4], efit[5], beta[5]]])

        m = r * b
        m = list(numpy.array(m.transpose()))
        r0 = lmap(lambda y: beta[3]**2 - vector.dot(y, y), m)
        #return r0

        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        r1 = lmap(lambda y, z: beta[6] - vector.dot(y, z), m, g)

        return r0 + r1
Esempio n. 15
0
    def biCGsolve(self, x0, b, tol=1.0e-10, nmax=1000):

        """
		Solve self*x = b and return x using the bi-conjugate gradient method
		"""

        try:
            if not vector.isVector(b):
                raise TypeError, self.__class__, " in solve "
            else:
                if self.size()[0] != len(b) or self.size()[1] != len(b):
                    print("**Incompatible sizes in solve")
                    print("**size()=", self.size()[0], self.size()[1])
                    print("**len=", len(b))
                else:
                    kvec = diag(self)  # preconditionner
                    n = len(b)
                    x = x0  # initial guess
                    r = b - dot(self, x)
                    rbar = r
                    w = r / kvec
                    wbar = rbar / kvec
                    p = vector.zeros(n)
                    pbar = vector.zeros(n)
                    beta = 0.0
                    rho = vector.dot(rbar, w)
                    err = vector.norm(dot(self, x) - b)
                    k = 0
                    print(" bi-conjugate gradient convergence (log error)")
                    while abs(err) > tol and k < nmax:
                        p = w + beta * p
                        pbar = wbar + beta * pbar
                        z = dot(self, p)
                        alpha = rho / vector.dot(pbar, z)
                        r = r - alpha * z
                        rbar = rbar - alpha * dot(pbar, self)
                        w = r / kvec
                        wbar = rbar / kvec
                        rhoold = rho
                        rho = vector.dot(rbar, w)
                        x = x + alpha * p
                        beta = rho / rhoold
                        err = vector.norm(dot(self, x) - b)
                        print(k, " %5.1f " % math.log10(err))
                        k = k + 1
                    return x

        except:
            print("ERROR ", self.__class__, "::biCGsolve")
Esempio n. 16
0
    def biCGsolve(self, x0, b, tol=1.0e-10, nmax=1000):
        """
		Solve self*x = b and return x using the bi-conjugate gradient method
		"""

        try:
            if not vector.isVector(b):
                raise TypeError, self.__class__, ' in solve '
            else:
                if self.size()[0] != len(b) or self.size()[1] != len(b):
                    print '**Incompatible sizes in solve'
                    print '**size()=', self.size()[0], self.size()[1]
                    print '**len=', len(b)
                else:
                    kvec = diag(self)  # preconditionner
                    n = len(b)
                    x = x0  # initial guess
                    r = b - dot(self, x)
                    rbar = r
                    w = r / kvec
                    wbar = rbar / kvec
                    p = vector.zeros(n)
                    pbar = vector.zeros(n)
                    beta = 0.0
                    rho = vector.dot(rbar, w)
                    err = vector.norm(dot(self, x) - b)
                    k = 0
                    print " bi-conjugate gradient convergence (log error)"
                    while abs(err) > tol and k < nmax:
                        p = w + beta * p
                        pbar = wbar + beta * pbar
                        z = dot(self, p)
                        alpha = rho / vector.dot(pbar, z)
                        r = r - alpha * z
                        rbar = rbar - alpha * dot(pbar, self)
                        w = r / kvec
                        wbar = rbar / kvec
                        rhoold = rho
                        rho = vector.dot(rbar, w)
                        x = x + alpha * p
                        beta = rho / rhoold
                        err = vector.norm(dot(self, x) - b)
                        print k, ' %5.1f ' % math.log10(err)
                        k = k + 1
                    return x

        except:
            print 'ERROR ', self.__class__, '::biCGsolve'
Esempio n. 17
0
	def biCGsolve(self,x0, b, tol=1.0e-10, nmax = 1000):
		
		"""
		Solve self*x = b and return x using the bi-conjugate gradient method
		"""

		try:
			if not vector.isVector(b):
				raise TypeError, self.__class__,' in solve '
			else:
				if self.size()[0] != len(b) or self.size()[1] != len(b):
					print '**Incompatible sizes in solve'
					print '**size()=', self.size()[0], self.size()[1]
					print '**len=', len(b)
				else:
					kvec = diag(self) # preconditionner 
					n = len(b)
					x = x0 # initial guess
					r =  b - dot(self, x)
					rbar =  r
					w = r/kvec;
					wbar = rbar/kvec;
					p = vector.zeros(n);
					pbar = vector.zeros(n);
					beta = 0.0;
					rho = vector.dot(rbar, w);
					err = vector.norm(dot(self,x) - b);
					k = 0
					print " bi-conjugate gradient convergence (log error)"
					while abs(err) > tol and k < nmax:
						p = w + beta*p;
						pbar = wbar + beta*pbar;
						z = dot(self, p);
						alpha = rho/vector.dot(pbar, z);
						r = r - alpha*z;
						rbar = rbar - alpha* dot(pbar, self);
						w = r/kvec;
						wbar = rbar/kvec;
						rhoold = rho;
						rho = vector.dot(rbar, w);
						x = x + alpha*p;
						beta = rho/rhoold;
						err = vector.norm(dot(self, x) - b);
						print k,' %5.1f ' % math.log10(err)
						k = k+1
					return x
			
		except: print 'ERROR ',self.__class__,'::biCGsolve'
Esempio n. 18
0
    def ray_collision(self, ray_origin, ray_direction, max_dist=-1):
        """ returns a list of pairs (object, point) where the ray hits this object, or an empty list if no hits"""
        offset = self.mPosition - ray_origin
        offset_mag_sq = vector.dot(offset, offset)

        # If this ray originates outside the circle (first clause) and is facing away from the sphere (second clause),
        # there can't be a hit -- no need to go farther
        if offset_mag_sq > self.mRadiusSquared and vector.dot(
                offset, ray_direction) < 0:
            return []

        para_dist = vector.dot(offset, ray_direction)
        para_dist_sq = para_dist**2
        perp_dist_sq = offset_mag_sq - para_dist_sq
        if perp_dist_sq <= self.mRadiusSquared:
            # The ray goes through the sphere.  Start to calculate the intersection points
            closest = ray_origin + para_dist * ray_direction
            if perp_dist_sq == self.mRadiusSquared:
                # Incredibly rare, but oh well.  Just one intersection at the tip of the sphere
                dist = (closest - ray_origin).magnitude()
                if max_dist < 0 or dist < max_dist:
                    return [closest]
                else:
                    return []
            else:
                closest_offset = (self.mRadiusSquared - perp_dist_sq)**0.5
                if offset_mag_sq < self.mRadiusSquared:
                    # The ray originates inside the sphere.  There will just be one collision
                    hit_pt = closest + closest_offset * ray_direction
                    dist = (hit_pt - ray_origin).magnitude()
                    if max_dist < 0 or dist < max_dist:
                        return [hit_pt]
                    else:
                        return []
                else:
                    # More common case: the ray originates outside, there're two collisions
                    hit_points = [
                        closest - closest_offset * ray_direction,
                        closest + closest_offset * ray_direction
                    ]
                    for i in range(len(hit_points) - 1, -1, -1):
                        dist = (hit_points[i] - ray_origin).magnitude()
                        if max_dist >= 0 and dist > max_dist:
                            del hit_points[i]
                    return hit_points

        # If we get here, no hits!
        return []
Esempio n. 19
0
def angle_3p(p1, p2, p3):
    """Returns the angle, in radians, rotating vector p2p1 to vector p2p3.
       arg keywords:
          p1 - a vector
          p2 - a vector
          p3 - a vector
       returns: a number
       In 2D, the angle is a signed angle, range [-pi,pi], corresponding
       to a clockwise rotation. If p1-p2-p3 is clockwise, then angle > 0.
       In 3D, the angle is unsigned, range [0,pi]
    """
    d21 = vector.norm(p2-p1)
    d23 = vector.norm(p3-p2)
    if tol_eq(d21,0) or tol_eq(d23,0):
        # degenerate, indeterminate angle
        return None
    v21 = (p1-p2) / d21
    v23 = (p3-p2) / d23
    t = vector.dot(v21,v23) # / (d21 * d23)
    if t > 1.0:             # check for floating point error
        t = 1.0
    elif t < -1.0:
        t = -1.0
    angle = math.acos(t)
    if len(p1) == 2:        # 2D case
        if is_counterclockwise(p1,p2,p3):
            angle = -angle
    return angle
Esempio n. 20
0
def ComputeDeviation(points, fit):
    m, d  = 0, 0
    for p in points:
        v = vector.sub(p[:3], fit[:3])
        m += (1 - vector.dot(v, v) / fit[3]**2)**2

        if len(fit) > 4:
            n = vector.dot(v, p[3:]) / vector.norm(v)
            if abs(n) <= 1:
                ang = math.degrees(math.asin(n))
                d += (fit[4] - ang)**2
            else:
                d += 1e111
    m /= len(points)
    d /= len(points)
    return [m**.5, d**.5]
Esempio n. 21
0
    def findAxisLeastPenetration(self, faceIndex, poly1, poly2):
        
        bestDistance = -1000000.0
        bestIndex = 0
        
        for i in range(poly1.vertexCount):
           
            #transform A's face normal int B's model space
            nw = poly1.u * poly1.normals[i]
            buT = poly2.u.transpose()
            n = buT * nw

            #retrieve support point from B along -n
            s = poly2.getSupport( -n )
            
            #retrieve vertex on face from A , transform into B's model space
            v = poly1.vertices[i]
            v = poly1.u * v + poly1.body.pos
            v -= poly2.body.pos
            v = buT * v
    
            #compute penetration ( in B's model)
            d = dot(n, s - v)
            
            if d > bestDistance:
                bestDistance = d
                bestIndex = i 
        
        faceIndex[0] = bestIndex    
        return bestDistance        
Esempio n. 22
0
def sss_int(p1, r1, p2, r2, p3, r3):
    """Intersect three spheres, centered in p1, p2, p3 with radius r1,r2,r3 respectively. 
       Returns a list of zero, one or two solution points.
    """
    solutions = []
    # plane though p1, p2, p3
    n = vector.cross(p2 - p1, p3 - p1)
    n = n / vector.norm(n)
    # intersect circles in plane
    cp1 = vector.vector([0.0, 0.0])
    cp2 = vector.vector([vector.norm(p2 - p1), 0.0])
    cpxs = cc_int(cp1, r1, cp2, r2)
    if len(cpxs) == 0:
        return []
    # px, rx, nx is circle
    px = p1 + (p2 - p1) * cpxs[0][0] / vector.norm(p2 - p1)
    rx = abs(cpxs[0][1])
    # plane of intersection cicle
    nx = p2 - p1
    nx = nx / vector.norm(nx)
    # print "px,rx,nx:",px,rx,nx
    # py = project p3 on px,nx
    dy3 = vector.dot(p3 - px, nx)
    py = p3 - (nx * dy3)
    if tol_gt(dy3, r3):
        return []
    ry = math.sin(math.acos(abs(dy3 / r3))) * r3
    # print "py,ry:",py,ry
    cpx = vector.vector([0.0, 0.0])
    cpy = vector.vector([vector.norm(py - px), 0.0])
    cp4s = cc_int(cpx, rx, cpy, ry)
    for cp4 in cp4s:
        p4 = px + (py - px) * cp4[0] / vector.norm(py - px) + n * cp4[1]
        solutions.append(p4)
    return solutions
Esempio n. 23
0
    def hit(self, ray: vector.Ray, t_min: float, t_max: float):

        oc = ray.origin - self.center
        a = ray.direction.length_squared()
        half_b = vector.dot(oc, ray.direction)
        c = oc.length_squared() - self.radius * self.radius
        discriminant = half_b * half_b - a * c

        if discriminant > 0:
            root = math.sqrt(discriminant)
            temp = (-half_b - root) / a
            if t_min < temp < t_max:
                hit_rec = HitRecord(None, None, None, None)
                hit_rec.t = temp
                hit_rec.position = ray.at(hit_rec.t)
                hit_rec.material = self.m
                outward_normal = (hit_rec.position - self.center).divide(
                    self.radius)
                hit_rec.set_face_normal(ray, outward_normal)
                return True, hit_rec

            temp = (-half_b + root) / a
            if t_min < temp < t_max:
                hit_rec = HitRecord(None, None, None, None)
                hit_rec.t = temp
                hit_rec.position = ray.at(hit_rec.t)
                hit_rec.material = self.m
                outward_normal = (hit_rec.position - self.center).divide(
                    self.radius)
                hit_rec.set_face_normal(ray, outward_normal)
                return True, hit_rec

        return False, None
Esempio n. 24
0
def matrix_multiply(A, B):
    if cols(A) != rows(B):
        raise RuntimeError(
            "Can't multiply matrices with dimensions {} and {}".format(
                shape(A), shape(B)))

    return [[dot(row, col) for col in zip(*B)] for row in A]
Esempio n. 25
0
    def set_face_normal(self, ray: vector.Ray, outward_normal: vector.Vec3):
        self.front_face = vector.dot(ray.direction, outward_normal) < 0

        if self.front_face:
            self.normal = outward_normal
        else:
            self.normal = -outward_normal
Esempio n. 26
0
def is_in_disk(q, Disk):
    p1 = Disk[0]
    p2 = Disk[1]

    if len(Disk) == 2:
        c2 = p1 + p2
        rad_vec = p1 * 2 - c2
        dist_vec = q * 2 - c2
        return vec.dot(dist_vec, dist_vec) <= vec.dot(rad_vec, rad_vec)

    if len(Disk) == 3:
        p3 = Disk[2]
        D, DX, DY = getD_DX_DY(p1, p2, p3)
        return ((D * q.x - DX) ** 2 + (D * q.y + DY) ** 2) <= ((D * p1.x - DX) ** 2 + (D * p1.y + DY) ** 2)

    return False
Esempio n. 27
0
def angle_3p(p1, p2, p3):
    """Returns the angle, in radians, rotating vector p2p1 to vector p2p3.
       arg keywords:
          p1 - a vector
          p2 - a vector
          p3 - a vector
       returns: a number
       In 2D, the angle is a signed angle, range [-pi,pi], corresponding
       to a clockwise rotation. If p1-p2-p3 is clockwise, then angle > 0.
       In 3D, the angle is unsigned, range [0,pi]
    """
    d21 = vector.norm(p2 - p1)
    d23 = vector.norm(p3 - p2)
    if tol_eq(d21, 0) or tol_eq(d23, 0):
        # degenerate, indeterminate angle
        return None
    v21 = (p1 - p2) / d21
    v23 = (p3 - p2) / d23
    t = vector.dot(v21, v23)  # / (d21 * d23)
    if t > 1.0:  # check for floating point error
        t = 1.0
    elif t < -1.0:
        t = -1.0
    angle = math.acos(t)
    if len(p1) == 2:  # 2D case
        if is_counterclockwise(p1, p2, p3):
            angle = -angle
    return angle
def stoch_descent(X, y, alpha, w):
    """
    Stochastic gradient descent
    :param X:
    :param y:
    :param alpha:
    :param w:
    :return:
    """
    global logs, logs_stoch
    logs = []
    logs_stoch = []
    random.seed(0)
    idx = list(range(len(X)))
    for epoch in range(1000):
        random.shuffle(idx)
        w_old = w
        for i in idx:
            loss = y[i] - vector.dot(X[i], w)
            gradient = vector.mul(loss, X[i])
            w = vector.add(w, vector.mul(alpha, gradient))
            logs_stoch += (w, alpha, sse(X, y, w))
        if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5:
            break
        logs += (w, alpha, sse(X, y, w))
    print("Epoch", epoch)
    return w
Esempio n. 29
0
 def point_inside(self, pt):
     offset = pt - self.mPosition
     for i in range(2):
         proj = abs(vector.dot(offset, self.mAxes[i]))
         if proj > self.mExtents[i]:
             return False
     return True
Esempio n. 30
0
    def scatter(self, ray_in: vector.Ray, hit_record: hittable.HitRecord):
        attenuation = vector.Vec3(1.0, 1.0, 1.0)
        etai_over_etat = self.ref_idx

        if hit_record.front_face:
            etai_over_etat = 1.0 / self.ref_idx

        unit_direction = vector.unit_vector(ray_in.direction)

        cos_theta = min(vector.dot(-unit_direction, hit_record.normal), 1.0)
        sin_theta = math.sqrt(1.0 - cos_theta*cos_theta)

        if etai_over_etat * sin_theta > 1.0:
            reflected = vector.reflect(unit_direction, hit_record.normal)
            scattered = vector.Ray(hit_record.position, reflected)
            return True, attenuation, scattered

        reflect_prob = vector.schlick(cos_theta, etai_over_etat)
        if util.random_double() < reflect_prob:
            reflected = vector.reflect(unit_direction, hit_record.normal)
            scattered = vector.Ray(hit_record.position, reflected)
            return True, attenuation, scattered

        refracted = vector.refract(unit_direction, hit_record.normal, etai_over_etat)
        scattered = vector.Ray(hit_record.position, refracted)
        return True, attenuation, scattered
Esempio n. 31
0
def is_right_handed(p1, p2, p3, p4):
    """return True if tetrahedron p1 p2 p3 p4 is right handed"""
    u = p2 - p1
    v = p3 - p1
    uv = vector.cross(u, v)
    w = p4 - p1
    return vector.dot(uv, w) > 0
Esempio n. 32
0
 def __init__(self, material, origin, norm, width, height):
     """Derives the base attributes from baseobject, but also takes a normal direction and point on the plane."""
     super().__init__(material, origin)
     self.norm = norm.normalized()
     self.distance = vector.dot(self.origin, self.norm)
     self.height = height
     self.width = width
Esempio n. 33
0
def stoch_descent(X, y, alpha, w):
    """
    Stochastic gradient descent
    :param X:
    :param y:
    :param alpha:
    :param w:
    :return:
    """
    global logs, logs_stoch
    logs = []
    logs_stoch = []
    random.seed(0)
    idx = list(range(len(X)))
    for epoch in range(1000):
        random.shuffle(idx)
        w_old = w
        for i in idx:
            loss = y[i] - vector.dot(X[i], w)
            gradient = vector.mul(loss, X[i])
            w = vector.add(w, vector.mul(alpha, gradient))
            logs_stoch += (w, alpha, sse(X, y, w))
        if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5:
            break
        logs += (w, alpha, sse(X, y, w))
    print("Epoch", epoch)
    return w
Esempio n. 34
0
def is_coplanar(p1,p2,p3,p4):
    """return True if tetrahedron p1 p2 p3 p4 is co-planar (not left- or right-handed)"""
    u = p2-p1
    v = p3-p1
    uv = vector.cross(u,v)
    w = p4-p1
    #return vector.dot(uv,w) == 0 
    return tol_eq(vector.dot(uv,w), 0) 
Esempio n. 35
0
def is_coplanar(p1, p2, p3, p4):
    """return True if tetrahedron p1 p2 p3 p4 is co-planar (not left- or right-handed)"""
    u = p2 - p1
    v = p3 - p1
    uv = vector.cross(u, v)
    w = p4 - p1
    #return vector.dot(uv,w) == 0
    return tol_eq(vector.dot(uv, w), 0)
Esempio n. 36
0
def is_left_handed(p1, p2, p3, p4):
    """return True if tetrahedron p1 p2 p3 p4 is left handed"""
    u = p2 - p1
    v = p3 - p1
    uv = vector.cross(u, v)
    w = p4 - p1
    #return vector.dot(uv,w) < 0
    return tol_lt(vector.dot(uv, w), 0)
Esempio n. 37
0
def vec2vec2quat(a, b):
    n = vector.cross(a, b)
    fac = vector.dot(a, b) / vector.norm(a) / vector.norm(b)
    fac = min(max(fac, -1),
              1)  # protect against possible slight numerical errors

    ang = math.acos(fac)
    return angvec2quat(ang, n)
Esempio n. 38
0
def is_right_handed(p1,p2,p3,p4):
    """return True if tetrahedron p1 p2 p3 p4 is right handed"""
    u = p2-p1
    v = p3-p1
    uv = vector.cross(u,v)
    w = p4-p1
    #return vector.dot(uv,w) > 0 
    return tol_gt(vector.dot(uv,w), 0) 
Esempio n. 39
0
def right_angle(v1, v2):
    x = vector.Vector(v1[0], v1[1])
    y = vector.Vector(v2[0], v2[1])
    dot = vector.dot(x, y)
    _angle = math.acos(dot / x.length() / y.length())
    if x[0] * y[1] < y[0] * x[1]:
        _angle = 2 * math.pi - _angle
    return _angle
Esempio n. 40
0
def right_angle(v1, v2):
    x = vector.Vector(v1[0], v1[1])
    y = vector.Vector(v2[0], v2[1])
    dot = vector.dot(x, y)
    _angle = math.acos(dot / x.length() / y.length())
    if x[0] * y[1] < y[0] * x[1]:
        _angle = 2 * math.pi - _angle
    return _angle
Esempio n. 41
0
def _perceptron(feature_vect, w, positive):
	r = v.dot(feature_vect, w)
	if positive and r<=0:
		return v.vec_add(w, feature_vect), False
	elif not positive and r>=0:
		return v.vec_sub(w, feature_vect), False
	else:
		return w, True
Esempio n. 42
0
 def on_ball_paddle_collision(self, ball_body, paddle_body, normal):
     # Adjusts the ball direction if the paddle is moving when the ball collides with it
     angle = math.acos(dot(normal, ball_body.direction)) # Angle between the reflected direction and the normal
     delta_angle = abs(((math.pi * 0.5) - angle) * 0.5) # Half the angle that remains if were to perform a 90 degree reflection
     if paddle_body.direction.x > 0: # Clockwise rotation because the paddle is moving to the right
         ball_body.direction = normalize(rotate(ball_body.direction, delta_angle))
     elif paddle_body.direction.x < 0: # Counter-clockwise rotation because the paddle is moving to the left
         ball_body.direction = normalize(rotate(ball_body.direction, -delta_angle))           
Esempio n. 43
0
 def rayTest(self, R):
     """Returns a list of sorted Raycollisions or none if its empty."""
     hits = []
     hat_rack = [
         self.Xhat, -self.Xhat, self.Yhat, -self.Yhat, self.Zhat, -self.Zhat
     ]
     hext_test = [
         self.hext.x, self.hext.x, self.hext.y, self.hext.y, self.hext.z,
         self.hext.z
     ]
     for i in range(6):
         norm = hat_rack[i]
         d = vector.dot((self.origin + (hext_test[i] * norm)), norm)
         if vector.dot(R.Dhat, norm) != 0:
             t = (d - vector.dot(R.origin, norm)) / (vector.dot(
                 R.Dhat, norm))
             if t < 0:
                 continue
             Pw = R.getPoint(t)
             Q = Pw - self.origin
             Pl = vector.Vector3(vector.dot(Q, self.Xhat),
                                 vector.dot(Q, self.Yhat),
                                 vector.dot(Q, self.Zhat))
             if -self.hext.x - 0.0001 <= Pl.x and Pl.x <= self.hext.x + 0.0001:
                 if -self.hext.y - 0.0001 <= Pl.y and Pl.y <= self.hext.y + 0.0001:
                     if -self.hext.z - 0.0001 <= Pl.z and Pl.z <= self.hext.z + 0.0001:
                         hits += [
                             Raycollision(R, self, t, R.getPoint(t), norm)
                         ]
     return hits
Esempio n. 44
0
    def align_squares(self, guess, cam_matrix, distortion_coefficients,
                      object_points):
        """
        Needed because ABCD has different camera location from BCDA. Takes a
        square's corners, camera intrisics, object information, and a camera
        rotation to align to. Finds the camera position that gives a rotation
        vector (unit vector in cam direction using grid axes) closest to guess.
        :param guess:
        :param cam_matrix:
        :param distortion_coefficients:
        :param object_points:
        :return: nothing
        """

        alignment_scores = [dot(self.cam_rot, guess), 0, 0, 0]

        # Loop through possible orders: ABCD, BCDA, CDAB, DABC
        for rot in range(1, 4):
            # Shift to the rot permutation
            temp_corners = np.roll(self.corners, rot, axis=0)

            # Get vector from camera to center of square
            temp_corners = temp_corners.reshape(4, 2, 1).astype(float)
            inliers, self.rvec, self.tvec = cv2.solvePnP(
                object_points, temp_corners, cam_matrix,
                distortion_coefficients)

            # Get rotation information for change to square center at origin
            rot_matrix = cv2.Rodrigues(self.rvec)

            cam_pos = np.multiply(cv2.transpose(rot_matrix[0]),
                                  -1).dot(self.tvec)
            cam_to_grid_transform = np.concatenate(
                (cv2.transpose(rot_matrix[0]), cam_pos), axis=1)

            # Compare camera unit vector to guess
            alignment_scores[rot] = dot(
                list(cam_to_grid_transform.dot(np.array([0, 0, 1, 0]))), guess)

        # Pick the orientation that was best and recompute camera location
        self.corners = np.roll(self.corners,
                               alignment_scores.index(max(alignment_scores)),
                               axis=0)
        self.update_pos_stats(cam_matrix, distortion_coefficients,
                              object_points)
Esempio n. 45
0
 def update(self, mouse, keys, dt):  #GRAVITY VELOCITY / ACCELERATION
     self.camera.update(mouse)
     self.rotation = self.camera.rotation
     wish_vector = vector.vec3()
     wish_vector.x = ((SDLK_d in keys) - (SDLK_a in keys))
     wish_vector.y = ((SDLK_w in keys) - (SDLK_s in keys))
     true_wish = wish_vector.rotate(0, 0, -self.rotation.z)
     self.front = vector.vec3(0, 1, 0).rotate(0, 0, -self.rotation.z)
     #GET CURRENT FRICTION (FROM SURFACE CONTACT)
     true_speed = self.speed * (1 if self.onGround else 1.75)
     self.position += true_wish * true_speed * dt  #NEED FRICTION
     if not self.onGround:
         self.velocity += 0.5 * vector.vec3(0, 0, -9.81) * dt  #GRAVITY
     self.onGround = False
     self.old_position = self.position
     self.position += self.velocity
     #min maxing old & new positions
     min_x = min(self.old_position.x, self.position.x)
     max_x = max(self.old_position.x, self.position.x)
     min_y = min(self.old_position.y, self.position.y)
     max_y = max(self.old_position.y, self.position.y)
     min_z = min(self.old_position.z, self.position.z)
     max_z = max(self.old_position.z, self.position.z)
     self.swept_aabb = aabb(
         vector.vec3(min_x, min_y, min_z) + self.aabb.min,
         vector.vec3(max_x, max_y, max_z) + self.aabb.max)
     global planes
     for plane in planes:  #filtered with position & bsp nodes
         #also should combine results rather than applying in order
         if self.swept_aabb.intersects(plane.aabb):
             p = vector.dot(self.position, plane.normal)
             max_p = self.swept_aabb.depth_along_axis(plane.normal)
             if p <= max_p and p <= abs(plane.distance):  # simplify
                 # push out of the plane, without changing velocity
                 self.position += math.fsum([plane.distance, -p
                                             ]) * plane.normal
                 # reset jump? (45 degree check)
                 if vector.dot(plane.normal,
                               vector.vec3(z=1)) <= math.sqrt(2):
                     self.onGround = True
                 self.velocity = vector.vec3()
                 #friction, surf & bounce
                 ##                    self.velocity -= self.velocity * plane.normal
                 if SDLK_SPACE in keys:  #JUMP
                     self.velocity.z += .6
Esempio n. 46
0
def paint_half_plane(xr, yr, v, sign, color):
    xl = []
    yl = []
    for x in xr:
        for y in yr:
            if sign * (vector.dot([1, -x], v) - y) > 0:
                xl.append(x)
                yl.append(y)
    plt.plot(xl, yl, color)
Esempio n. 47
0
def is_counterclockwise(p1,p2,p3):
    """ returns True iff triangle p1,p2,p3 is counterclockwise oriented"""
    assert len(p1)==2
    assert len(p1)==len(p2)
    assert len(p2)==len(p3)   
    u = p2 - p1
    v = p3 - p2;
    perp_u = vector.vector([-u[1], u[0]])
    return tol_gt(vector.dot(perp_u,v), 0)
Esempio n. 48
0
 def get_color(self, p):
     '''
         :param Vector3D p: ??
     '''
     if self._angle < math.acos(vector.dot(self._direction,
                                           p - self._position) /
                               (p - self._position).length):
         return color.RaytracerColor()
     return self._color
Esempio n. 49
0
def paint_half_plane(xr, yr, v, sign, color):
    xl = []
    yl = []
    for x in xr:
        for y in yr:
            if sign * (vector.dot([1, -x], v) - y) > 0:
                xl.append(x)
                yl.append(y)
    plt.plot(xl, yl, color)
Esempio n. 50
0
 def intersect_circle(self, c):
     d = self.b - self.a
     f = self.a - c.center
     a = dot(d, d)
     b = 2 * dot(f, d)
     c = dot(f, f) - c.radius * c.radius
     discriminant = b * b - 4 * a * c
     if discriminant < 0:
         # no intersection
         return None
     else:
         discriminant = sqrt(discriminant)
         t1 = (-b - discriminant) / (2.0 * a)
         t2 = (-b + discriminant) / (2.0 * a)
         if t1 >= 0 and t1 <= 1:
             return True
         if t2 >= 0 and t2 <= 1:
             return True
         return None
Esempio n. 51
0
def sse(X, y, w):
    """
    Sum of squared errors
    :param X:
    :param y:
    :param w:
    :return:
    """
    error = vector.sub(y, vector.mul_mat_vec(X, w))
    return vector.dot(error, error)
Esempio n. 52
0
    def on_ball_left_right_collision(self, ball_body, wall_body, normal):
        angle = math.acos(dot(normal, ball_body.direction)) # Angle between the reflected direction and the normal

        # If the angle is too flat, add a small rotation to the reflected direction
        if angle < 0.1:
            delta_angle = 0.2
            if ball_body.direction.y > 0: # Counter-clockwise rotation because the ball is moving downwards
                ball_body.direction = normalize(rotate(ball_body.direction, -delta_angle))
            elif ball_body.direction.y <= 0: # Clockwise rotation because the ball is moving upwards 
                ball_body.direction = normalize(rotate(ball_body.direction, delta_angle))   
Esempio n. 53
0
    def CGsolve(self, x0, b, tol=1.0e-10, nmax=1000, verbose=1):
        """
		Solve self*x = b and return x using the conjugate gradient method
		"""
        if not vector.isVector(b):
            raise TypeError, self.__class__, " in solve "
        else:
            if self.size()[0] != len(b) or self.size()[1] != len(b):
                print("**Incompatible sizes in solve")
                print("**size()=", self.size()[0], self.size()[1])
                print("**len=", len(b))
            else:
                kvec = diag(self)  # preconditionner
                n = len(b)
                x = x0  # initial guess
                r = b - dot(self, x)
                try:
                    w = r / kvec
                except:
                    print("***singular kvec")
                p = vector.zeros(n)
                beta = 0.0
                rho = vector.dot(r, w)
                err = vector.norm(dot(self, x) - b)
                k = 0
                if verbose:
                    print(" conjugate gradient convergence (log error)")
                while abs(err) > tol and k < nmax:
                    p = w + beta * p
                    z = dot(self, p)
                    alpha = rho / vector.dot(p, z)
                    r = r - alpha * z
                    w = r / kvec
                    rhoold = rho
                    rho = vector.dot(r, w)
                    x = x + alpha * p
                    beta = rho / rhoold
                    err = vector.norm(dot(self, x) - b)
                    if verbose:
                        print(k, " %5.1f " % math.log10(err))
                    k = k + 1
                return x
Esempio n. 54
0
def cr_int(p1,r,p2,v):
    """
    Intersect a circle (p1,r) with ray (p2,v) (a half-line)
    where p1, p2 and v are 2-vectors, r is a scalar
    Returns a list of zero, one or two solutions.
    """
    sols = []
    all = cl_int(p1,r,p2,v)
    for s in all: 
        if tol_gte(vector.dot(s-p2,v), 0):          
            sols.append(s)
    return sols
Esempio n. 55
0
def sss_int(p1, r1, p2, r2, p3, r3):
    """Intersect three spheres, centered in p1, p2, p3 with radius r1,r2,r3 respectively. 
       Returns a list of zero, one or two solution points.
    """
    solutions = []
    # intersect circles in plane
    cp1 = vector.vector([0.0,0.0]) 
    cp2 = vector.vector([vector.norm(p2-p1), 0.0])
    cpxs = cc_int(cp1, r1, cp2, r2)
    if len(cpxs) == 0:
        return []
    # determine normal of plane though p1, p2, p3
    n = vector.cross(p2-p1, p3-p1)
    if not tol_eq(vector.norm(n),0.0):  
        n = n / vector.norm(n)
    else:
        # traingle p1, p2, p3 is degenerate
        # check for 2d solutions
        if len(cpxs) == 0:
            return []
        # project cpxs back to 3d and check radius r3 
        cp4 = cpxs[0]
        u = normalised(p2-p1)
        v,w = perp_3d(u)
        p4 = p1 + cp4[0] * u + cp4[1] * v
        if tol_eq(vector.norm(p4-p3), r3):
            return [p4]
        else:
            return []
    # px, rx, nx is circle 
    px = p1 + (p2-p1) * cpxs[0][0] / vector.norm(p2-p1)
    rx = abs(cpxs[0][1])
    nx = p2-p1
    nx = nx / vector.norm(nx)
    # py is projection of p3 on px,nx
    dy3 = vector.dot(p3-px, nx)
    py = p3 - (nx * dy3)
    if tol_gt(dy3, r3):
        return []
    # ry is radius of circle in py
    if tol_eq(r3,0.0):
        ry = 0.0 
    else:   
        ry = math.sin(math.acos(min(1.0,abs(dy3/r3))))*r3
    # determine intersection of circle px, rx and circle py, ry, projected relative to line py-px 
    cpx = vector.vector([0.0,0.0]) 
    cpy = vector.vector([vector.norm(py-px), 0.0])
    cp4s = cc_int(cpx, rx, cpy, ry)
    for cp4 in cp4s:
        p4 = px + (py-px) * cp4[0] / vector.norm(py-px) + n * cp4[1] 
        solutions.append(p4)  
    return solutions
Esempio n. 56
0
def distance_point_line(p,l1,l2):
    """distance from point p to line l1-l2"""
    # v,w is p, l2 relative to l1
    v = p-l1
    w = l2-l1
    # x = projection v on w
    lw = vector.norm(w)
    if tol_eq(lw,0):
        x = 0*w
    else:
        x = w * vector.dot(v,w) / lw
    # result is distance x,v
    return vector.norm(x-v)
Esempio n. 57
0
    def align_squares(self, guess, cam_matrix, distortion_coefficients, object_points):
        """
        Needed because ABCD has different camera location from BCDA. Takes a
        square's corners, camera intrisics, object information, and a camera
        rotation to align to. Finds the camera position that gives a rotation
        vector (unit vector in cam direction using grid axes) closest to guess.
        :param guess:
        :param cam_matrix:
        :param distortion_coefficients:
        :param object_points:
        :return: nothing
        """

        alignment_scores = [dot(self.cam_rot, guess), 0, 0, 0]

        # Loop through possible orders: ABCD, BCDA, CDAB, DABC
        for rot in range(1, 4):
            # Shift to the rot permutation
            temp_corners = np.roll(self.corners, rot, axis=0)

            # Get vector from camera to center of square
            temp_corners = temp_corners.reshape(4,2,1).astype(float)
            inliers, self.rvec, self.tvec = cv2.solvePnP(object_points, temp_corners,
                                                         cam_matrix, distortion_coefficients)

            # Get rotation information for change to square center at origin
            rot_matrix = cv2.Rodrigues(self.rvec)

            cam_pos = np.multiply(cv2.transpose(rot_matrix[0]), -1).dot(self.tvec)
            cam_to_grid_transform = np.concatenate((cv2.transpose(rot_matrix[0]), cam_pos), axis=1)

            # Compare camera unit vector to guess
            alignment_scores[rot] = dot(list(cam_to_grid_transform.dot(np.array([0, 0, 1, 0]))), guess)

        # Pick the orientation that was best and recompute camera location
        self.corners = np.roll(self.corners, alignment_scores.index(max(alignment_scores)), axis=0)
        self.update_pos_stats(cam_matrix, distortion_coefficients, object_points)
Esempio n. 58
0
    def can_go_home(self, bag):
        """
        Checks if the stick can go home.
        :param bag: The parameter bag.
        :return:
        """

        # no detected puck movement: go home
        if 'direction' not in bag.puck:
            return True

        # nothing to do if the puck is not here
        if bag.puck.position[0] < 0.2:
            return True

        # check if the puck is flying away from home
        return vector.dot(self.AWAY_FROM_HOME, bag.puck.direction) > 0.25
Esempio n. 59
0
 def intersect(self, ray):
     oc = self.center - ray.orig
     # let P be projection of C on the line
     # then l = |OP|, h = |CP|
     l = dot(oc, ray.dir)
     h = cross(oc, ray.dir)
     if self.radius < abs(h):
         return None
     q = sqrt(self.radius ** 2 - h ** 2)
     # find t: o + d * t == intersection
     t = l - q
     if t < 0:
         t = l + q
     if t < 0:
         return None
     else:
         return ray.orig + t * ray.dir
Esempio n. 60
0
def line_segment_point_distance(point, seg):
    seg_start = vector.Vector(seg[0][0], seg[0][1])
    seg_end = vector.Vector(seg[1][0], seg[1][1])
    x, y = point
    point = vector.Vector(x, y)

    seg_dir = seg_end - seg_start
    seg_length = seg_dir.length()**2
    if seg_length == 0:
      return (point - seg_start).length()

    t = vector.dot(point - seg_start, seg_dir) / seg_length
    if t < 0:
      return (point - seg_start).length()
    elif t > 1:
      return (point - seg_end).length()

    projection = seg_start + t * seg_dir
    return (point - projection).length()