示例#1
0
def cylinder(w,h):
    """Generate DCEL for a triangulated cylinder of height h and circumference w"""
    tops = []
    bottoms = []
    D = dcel.DCEL()

    # Create h separate rings of height 1
    for i in range(h):
        RD,t,b = ring(w)
        tops.append(t)
        bottoms.append(b)
        D |= RD

    # Glue the rings top-to-bottom
    for i in range(h-1):
        dcel.glue_boundary(D, bottoms[i], tops[i + 1])

    return D,tops[0],bottoms[-1]
示例#2
0
def embedded_cylinder(nw, nh, coord_gen):
    """Generate DCEL for a triangulated cylinder of height h and circumference w"""
    tops = []
    bottoms = []
    D = dcel.DCEL()

    # Create h separate rings of height 1
    for i in range(nh):
        RD, t, b = embedded_ring(nw, i, coord_gen=coord_gen)
        tops.append(t)
        bottoms.append(b)
        D |= RD

    # Glue the rings top-to-bottom
    for i in range(nh - 1):
        dcel.glue_boundary(D, bottoms[i], tops[i + 1])

    return D, tops[0], bottoms[-1]
示例#3
0
def ring(w):
    """Generate DCEL for a triangulated ring of height 1 and circumference w.

    Looks like:.. --T----------------...
                  |\  |\  |\  |\  |\
                \ | \ | \ | \ | \ | \
                 \|  \|  \|  \|  \|  \
                ..--B-----------------...
    Returns typle (D,T,B)
    D -- DCEL of the ring
    T -- a "top" half-edge
    B -- a "bottom" half edge directly below T
    """

    # We create the vertices first in a 2d array; later the indices
    # will correspond to position in the ring as follows:
    #
    # 00---01---02---03---04---05
    # |\   |\   |\   |\   |\   |
    # | \  | \  | \  | \  | \  |
    # |  \ |  \ |  \ |  \ |  \ | 
    # |   \|   \|   \|   \|   \|
    # 10---11---12---13---14---15
    

    V = [[dcel.Vertex() for i in range(w)],
         [dcel.Vertex() for i in range(w)]]

    E = set()
    F = set()

    # Top triangles
    for i in range(w):
        j = (i+1) % w
        EF,f = dcel.vertex_chain_to_face([V[1][j], V[0][j], V[0][i]])
        if i == 0:
            for e in EF:
                if e.src == V[0][1] and e.dst == V[0][0]:
                    etop = e
                    break
        E.update(EF)
        F.add(f)

    # Bottom triangles
    for i in range(w):
        j = (i+1) % w
        EF,f = dcel.vertex_chain_to_face([V[0][i], V[1][i], V[1][j]])
        if i == 0:
            for e in EF:
                if e.src == V[1][0] and e.dst == V[1][1]:
                    ebot = e
                    break
        E.update(EF)
        F.add(f)

    # TODO: inefficient to search blindly for twin pairs, when we know
    # exactly which ones are present.  Make this more efficient.
    # (Since vertex_chain_to_face doesn't expose any details about the
    # order of edges returned, it is probably best to just manually
    # create all of half-edges and store in an array like V.
    dcel.set_twins(E)

    return dcel.DCEL(V[0] + V[1], E, F), etop, ebot
示例#4
0
    def drawTest_old(self):
        """ a grab bag of tests"""
        self.ctx.set_source_rgba(*COLOUR)
        # p = [0.3,0.6]
        # l = 0.9

        # utils.drawCircle(self.ctx,p[0],p[1],0.005)

        # line = utils.createLine(0,l,1,l,1000)
        # for x,y in line:
        #     utils.drawCircle(self.ctx,x,y,0.002)

        # par = makeParabola(p,l,np.linspace(0,1,1000))
        # print(par)
        # for x,y in par:
        #     utils.drawCircle(self.ctx,x,y,0.002)

        #DCEL Test:
        dc = dcel.DCEL()
        v1 = dc.newVertex(0.2, 0.2)
        v2 = dc.newVertex(0.4, 0.2)
        v3 = dc.newVertex(0.5, 0.6)
        e1 = dc.newEdge(v1, v2)
        e2 = dc.newEdge(v2, v3)
        e3 = dc.newEdge(v3, v1)
        f1 = dc.newFace()
        dc.linkEdgesTogether([e1, e2, e3])
        dc.setFaceForEdgeLoop(f1, e1)
        #utils.drawDCEL(self.ctx,dc)

        #Draw an arc:
        centre = np.array([[0.5, 0.5]])
        r = 0.2
        rads = pi / 2
        self.ctx.set_line_width(0.002)
        for xy in centre:
            self.ctx.arc(*xy, r, 0, rads)
        self.ctx.stroke()

        #Draw the end points
        p1 = centre + [r, 0]
        p2 = utils.rotatePoint(p1, centre, rads)
        utils.drawCircle(self.ctx, *centre[0], 0.006)
        utils.drawCircle(self.ctx, *p1[0], 0.006)
        utils.drawCircle(self.ctx, *p2[0], 0.006)
        #draw a chord:
        self.ctx.move_to(*p1[0])
        self.ctx.line_to(*p2[0])
        self.ctx.stroke()

        #midpoint:
        e = 1  #direction 1/-1 counter/clockwise
        d = utils.get_distance(p1, p2)
        m = utils.get_midpoint(p1, p2)
        utils.drawCircle(self.ctx, *m[0], 0.006)
        #normal:
        n = utils.get_normal(p1, p2)
        bisector = utils.get_bisector(p1, p2)
        h = np.sqrt(pow(r, 2) - (pow(d, 2) / 4))  #height from centre
        c = m + (e * h * bisector)  #centre calculated
        self.ctx.move_to(*m[0])
        self.ctx.line_to(*c[0])
        self.ctx.stroke()

        #extend a line:
        self.ctx.set_source_rgba(0.8, 0.6, 0.2, 1)
        extend_point = p2
        extend_distance = 5
        extended_line = utils.extend_line(p1, p2, extend_distance)
        self.ctx.move_to(*extend_point[0])
        self.ctx.line_to(*extended_line[0])
        self.ctx.stroke()

        #clip the line
        self.ctx.set_source_rgba(0.5, 0.1, 0.1, 1)
        clippedLine = utils.bound_line_in_bbox(
            np.row_stack((extend_point, extended_line)), [0.5, 0, 1, 1])
        self.ctx.move_to(*clippedLine[0])
        self.ctx.line_to(*clippedLine[1])
        self.ctx.stroke()

        #intersect two lines
        l1 = utils.random_points(2)
        l2 = utils.random_points(2)
        #l1 = np.array([0.2,0.2,0.4,0.4])
        #l2 = np.array([0.4,0.2,0.2,0.4])
        self.ctx.move_to(l1[0], l1[1])
        self.ctx.line_to(l1[2], l1[3])
        self.ctx.stroke()
        self.ctx.move_to(l2[0], l2[1])
        self.ctx.line_to(l2[2], l2[3])
        self.ctx.stroke()

        intersect = utils.intersect(l1, l2)
        print(intersect)
        if intersect is not None:
            utils.drawCircle(self.ctx, *intersect, 0.005)