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]
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]
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
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)