Esempio n. 1
0
def clip_line(line, boundaries):
    p0 = line[0]
    p1 = line[1]

    a = 0.
    b = 1.
    p0_all_safe, p1_all_safe = False, False

    for boundary in boundaries:

        n = boundary.normal
        th = boundary.threshold

        p0n = vec.dot(p0, n)
        p1n = vec.dot(p1, n)

        p0_safe = p0n >= th
        p1_safe = p1n >= th

        if p0_safe and p1_safe:
            a = 0
            b = 1
            p0_all_safe = True
            p1_all_safe = True
            break
        #print('p0,p1 safe',p0_safe,p1_safe)
        if p0_safe and (not p1_safe):
            t_intersect = (p0n - th) / (p0n - p1n)
            a = max(a, t_intersect)
            #print('move a to',a)
        if (not p0_safe) and p1_safe:
            t_intersect = (p0n - th) / (p0n - p1n)
            b = min(t_intersect, b)
            #print('move b to',b)
        p0_all_safe = (p0_all_safe or p0_safe)
        p1_all_safe = (p1_all_safe or p1_safe)

    #print('all_safe',p0_all_safe,p1_all_safe)
    #both endpoints visible
    if p0_all_safe and p1_all_safe:
        #return two lines if we've intersected the shape
        if a > 0 and b < 1:
            return [
                Line(p0, vec.linterp(p0, p1, a)),
                Line(vec.linterp(p0, p1, b), p1)
            ]
        else:
            #return entire line if we haven't intersected the shape
            return [line]
    if p0_all_safe and (not p1_all_safe):
        return [Line(p0, vec.linterp(p0, p1, a))]
    if (not p0_all_safe) and p1_all_safe:
        return [Line(vec.linterp(p0, p1, b), p1)]
    #if neither point is visible, don't draw the line
    return []
Esempio n. 2
0
def clip_line_plane(line, plane, small_z=0):
    p0 = line[0]
    p1 = line[1]

    n = plane.normal
    th = plane.threshold + small_z

    p0n = vec.dot(p0, n)
    p1n = vec.dot(p1, n)

    p0_safe = p0n >= th
    p1_safe = p1n >= th
    #if both vertices are behind, draw neither
    if (not p0_safe) and (not p1_safe):
        return None
    #both vertices in front
    if p0_safe and p1_safe:
        return line
    #if one of the vertices is behind the camera
    t_intersect = (p0n - th) / (p0n - p1n)
    intersect = vec.linterp(p0, p1, t_intersect)
    if (not p0_safe) and p1_safe:
        return Line(intersect, p1)
    else:
        return Line(p0, intersect)
Esempio n. 3
0
def calc_boundary(face1, face2, origin):

    n1 = face1.normal
    n2 = face2.normal
    th1 = face1.threshold
    th2 = face2.threshold

    #k1 and k2 must be opposite signs
    k1 = vec.dot(n1, origin) - th1
    k2 = vec.dot(n2, origin) - th2

    t = k1 / (k1 - k2)

    n3 = vec.linterp(n1, n2, t)
    th3 = vec.linterp(th1, th2, t)

    return HyperPlane(n3, th3)
Esempio n. 4
0
def draw_face_fuzz_old(face, camera, shape, shapes):
    #weights = np.random.uniform(size=[n_points,len(verts)])
    #weights = weights/np.sum(weights,axis=1,keepdims=True)
    #points = np.dot(weights,verts)

    verts = [shape.verts[i] for i in face.get_verts(shape)]
    #points = [vec.linterp(verts[0], verts[1], t[0]) + vec.linterp(verts[0], verts[2], t[1]) for t in t_vals]
    if this.d == 3:
        points = [
            vec.linterp(vec.linterp(verts[0], verts[1], t[0]),
                        vec.linterp(verts[2], verts[3], t[0]), t[1])
            for t in this.random_fuzz
        ]
    if this.d == 4:
        points = [
            vec.linterp(
                vec.linterp(vec.linterp(verts[0], verts[1], t[0]),
                            vec.linterp(verts[2], verts[3], t[0]), t[1]),
                vec.linterp(vec.linterp(verts[4], verts[5], t[0]),
                            vec.linterp(verts[6], verts[7], t[0]), t[1]), t[2])
            for t in this.random_fuzz
        ]
    #print(points.shape)
    if this.clipping:
        clipped = [False for i in range(len(points))]
        for clipping_shape in shapes:
            if (clipping_shape
                    is not shape) and (not clipping_shape.transparent):
                new_clipped = [
                    Clipping.point_clipped(point, clipping_shape.boundaries)
                    for point in points
                ]
                clipped = [
                    clip1 or clip2
                    for clip1, clip2 in zip(clipped, new_clipped)
                ]
        clipped_points = [
            point for point, clip in zip(points, clipped) if (not clip)
        ]
        if len(clipped_points) < 1:
            return
        draw_points(camera, clipped_points, face.color)
    else:
        draw_points(camera, points, face.color)
Esempio n. 5
0
def line_plane_intersect(line, plane):
    p0 = line[0]
    p1 = line[1]
    n = plane.normal
    th = plane.threshold
    p0n = vec.dot(p0, n)
    p1n = vec.dot(p1, n)
    #line is contained in plane
    if vec.isclose(p0n, 0) and vec.isclose(p1n, 0):
        return None
    #plane does not intersect line segment
    t = (p0n - th) / (p0n - p1n)
    if t < 0 or t > 1:
        return None
    return vec.linterp(p0, p1, t)
Esempio n. 6
0
 def scale_point(p, scale):
     return vec.linterp(face.center, p, scale)
Esempio n. 7
0
def clip_line_cylinder(line, r, h, axis):
    def make_line(u0, u1, a0, a1, axis):
        return Line(vec.insert_index(u0, axis, a0),
                    vec.insert_index(u1, axis, a1))

    half_h = h / 2

    v0 = line[0]
    v1 = line[1]
    #components parallel to axis
    a0 = v0[axis]
    a1 = v1[axis]
    #components perpendicular to axis
    u0 = vec.drop_index(v0, axis)
    u1 = vec.drop_index(v1, axis)
    #line is outside
    if (a0 > half_h and a1 > half_h) or (a0 < -half_h and a1 < -half_h):
        return None

    #clip lines to be within cylinder radius
    #would be nice if we could neatly merge this functionality with sphere clipping
    t_roots = sphere_t_intersect(Line(u0, u1), r)
    u0_in_circle = vec.dot(u0, u0) < r * r
    u1_in_circle = vec.dot(u1, u1) < r * r

    if u0_in_circle and u1_in_circle:
        circ_line = Line(u0, u1)
    else:
        if (not u0_in_circle) and (not u1_in_circle):
            #(extended) line does not intersect circle
            if t_roots is None:
                return None
            #check to see if segment intersecs
            #need only check one root to see if line segment intersects
            if t_roots[0] < 0 or t_roots[0] > 1:
                return None
            else:
                circ_line = Line(vec.linterp(u0, u1, t_roots[0]),
                                 vec.linterp(u0, u1, t_roots[1]))
                new_a0 = vec.linterp(a0, a1, t_roots[0])
                new_a1 = vec.linterp(a0, a1, t_roots[1])
                a0 = new_a0
                a1 = new_a1
        else:
            if u0_in_circle and (not u1_in_circle):
                #print("u0 in",tm,tp,line)
                circ_line = Line(u0, vec.linterp(u0, u1, t_roots[1]))
                a1 = vec.linterp(a0, a1, t_roots[1])
            else:
                #print("u1 in",tm,tp,line)
                circ_line = Line(vec.linterp(u0, u1, t_roots[0]), u1)
                a0 = vec.linterp(a0, a1, t_roots[0])

    new_line = make_line(circ_line[0], circ_line[1], a0, a1, axis)

    #clip top and bottom of cylinder
    d = vec.dim(v0)
    clipped_line = clip_line_plane(new_line,
                                   HyperPlane(-vec.one_hot(d, axis), -half_h))
    if clipped_line is None:
        return None

    clipped_line = clip_line_plane(clipped_line,
                                   HyperPlane(vec.one_hot(d, axis), -half_h))

    return clipped_line
Esempio n. 8
0
def plane0_intersect(v1, v2,
                     z0):  #point of intersection with plane at x[-1] = z0
    t = (v1[-1] - z0) / (v1[-1] - v2[-1])
    return vec.linterp(v1, v2, t)