Exemple #1
0
 def test_sub(self):
     v = Vector(3, 5, 1)
     b = Vector(1, 0, 2)
     r = v.sub(b)
     self.assertEqual(r.x, 2)
     self.assertEqual(r.y, 5)
     self.assertEqual(r.z, -1)
Exemple #2
0
class Light(AmbientLight):
    """Subclass of AmbientLight
        It is used to position point Lights to the scene with a certain position (self.position)
    """
    def __init__(self, position=Vector(0, 0, 0), brightness=0.1):
        AmbientLight.__init__(self, brightness)
        self.position = position

    def __init__(self, x=0, y=0, z=0, brightness=0.1):
        AmbientLight.__init__(self, brightness)
        self.position = Vector(x, y, z)

    def getLightRay(self, point):
        lightRay = Ray(self.position, point)
        return lightRay

    def getLightVector(self, point):
        lightVector = self.position.sub(point)
        return lightVector

    def getPosition(self):
        return self.position
Exemple #3
0
class Cylinder(Object3D):
    """Basic class that implements object Cylinder and the intersection of a cylinder to a ray"""
    def __init__(self,
                 x=0,
                 y=0,
                 z=0,
                 height=0,
                 radius=0,
                 color=Color(),
                 specular=50,
                 reflection=0.1,
                 transparency=0,
                 refractiveIndex=1.0):
        super().__init__(x, y, z, color, specular, reflection, transparency,
                         refractiveIndex)
        self.radius = radius
        self.height = height
        self.top = Vector(x, y + height / 2, z)
        self.bottom = Vector(x, y - height / 2, z)
        self.va = self.top.sub(self.center).normalize()

    def __init__(self,
                 v=Vector(0, 0, 0),
                 height=0,
                 radius=0,
                 color=Color(),
                 specular=50,
                 reflection=0.1,
                 transparency=0,
                 refractiveIndex=1.0):
        super().__init__(v, color, specular, reflection, transparency,
                         refractiveIndex)
        self.radius = radius
        self.height = height
        self.top = Vector(v.x, v.y + height / 2, v.z)
        self.bottom = Vector(v.x, v.y - height / 2, v.z)
        self.va = self.top.sub(self.center).normalize()

    def intersection(self, ray, tMin, tMax):

        deltaP = ray.startPoint.sub(self.center)

        partA = ray.direction.sub(
            self.va.multiply(ray.direction.dotProduct(self.va)))
        a = partA.dotProduct(partA)
        dotProd = deltaP.dotProduct(self.va)
        partB = deltaP.sub(self.va.multiply(dotProd))
        b = 2 * partA.dotProduct(partB)
        c = partB.dotProduct(partB) - self.radius * self.radius

        t = MathUtil().solveQuadraticFormula(a, b, c)

        intersect = None

        if t is not None:
            tSmallest = math.inf
            if tMin < t.getx1() < tMax and t.getx1() < tSmallest:
                tSmallest = t.getx1()
            if tMin < t.getx2() < tMax and t.getx2() < tSmallest:
                tSmallest = t.getx2()

            if tSmallest == math.inf:
                return None

            point = ray.getPointOfRay(tSmallest)
            intersect = Intersection(point, self, ray, tSmallest)

            if not self.inCylinder(point):
                tmp = None
                if self.isAbove(point):
                    tmp = self.intersect_base(ray, self.top, Vector(0, 1, 0))
                else:
                    tmp = self.intersect_base(ray, self.bottom,
                                              Vector(0, -1, 0))

                if tmp:
                    intersect.point = tmp.point
                else:
                    intersect = None

        return intersect

    def intersect_base(self, ray, center, normal):
        bottom = Plane(center, normal)
        intersection = bottom.intersection(ray, 0.001, 100000)
        if intersection:
            v = intersection.point.sub(bottom.center)
            if v.calcLength() > self.radius:
                intersection = None

        return intersection

    def getSurfaceNormal(self, point):

        surfaceNormal = Vector()

        if self.center.x - self.radius <= point.x <= self.center.x + self.radius and self.center.z - self.radius <= point.z <= self.center.z + self.radius:

            epsilon = 0.00001

            if point.y > self.top.y - epsilon:
                return Vector(0.0, 1.0, 0.0)
            elif self.bottom.y - epsilon < point.y < self.bottom.y + epsilon:
                return Vector(0.0, -1.0, 0.0)

            v = Vector(self.center.x, point.y, self.center.z)
            surfaceNormal = point.sub(v)

        return surfaceNormal.normalize()

    def inCylinder(self, point):
        if point.y < self.bottom.y or point.y > self.top.y:
            return False
        else:
            return True

    def isAbove(self, point):
        if point.y > self.center.y:
            return True
        else:
            return False