def update_dual_roaming(j,n_fixed,n_roam,j_prime): jp_seg=g_prime.nodes['x'][g_prime.edges['nodes'][j_prime]] jp_vec=jp_seg[1,:] - jp_seg[0,:] jp_vec=jp_vec / utils.mag(jp_vec) vec_perp=np.array([jp_vec[1],-jp_vec[0]]) f_roam=lambda d: g_dual.nodes['x'][n_fixed] + d*vec_perp d0=np.dot(vec_perp,g_dual.nodes['x'][n_roam]-g_dual.nodes['x'][n_fixed]) if d0<0: # clarify orientation d0*=-1 vec_perp*=-1 # rather than maintaining length of the original edge, better # to relationship with prime's nodes. # I think this equivalent to making the length double the # distance from n_fixed to the edge j_prime (or distance # to one of j_prime's nodes, projected onto vec_perp if 1: # preserve prime's nodes delta=jp_seg[0,:] - g_dual.nodes['x'][n_fixed] d_target=2*np.dot(delta,vec_perp) new_roam=f_roam(d_target) else: # preserves length of the edge: new_roam=f_roam(d0) # just move it halfway - seems like going all the way causes # oscillations new_roam=0.5*(new_roam+g_dual.nodes['x'][n_roam]) g_dual.modify_node(n_roam,x=new_roam)
def link_cost_angle(g,j): vc=g.cells_center() c1,c2=g.edges['cells'][j] n1,n2=g.edges['nodes'][j] assert c1>=0 assert c2>=0 vec_norm=vc[c2]-vc[c1] vec_tan =g.nodes['x'][n1]- g.nodes['x'][n2] vec_norm=vec_norm/utils.mag(vec_norm) vec_tan =vec_tan/utils.mag(vec_tan) parallel=(vec_norm*vec_tan).sum() return np.abs(parallel) # |cos(theta)|
def get_output_vector(self, game_tick_packet): s = EasyGameState(game_tick_packet, self.team, self.index) speed = mag(s.car_vel) turn_rate = game_tick_packet.gamecars[ self.index].AngularVelocity.Z # rad/s turn_radius = speed / max(turn_rate, 0.001) if self.start_time is None: self.start_time = s.time time_elapsed = s.time - self.start_time desired_speed = 10 + time_elapsed * 100 too_slow = desired_speed > speed should_boost = desired_speed > 1000 and too_slow pedal = too_slow if desired_speed < 500: pedal *= 0.5 trace(speed) # trace(turn_rate) trace(turn_radius) # trace(desired_speed) trace(turn_radius - estimate_turn_radius(speed)) output_vector = [ pedal, # fThrottle 1, # fSteer 0, # fPitch 0, # fYaw 0, # fRoll 0, # bJump should_boost, # bBoost 0, # bHandbrake ] if not controller.hat_toggle_west: if self.measurements: print('TADA:') print(repr(self.measurements)) output_vector = ( round(controller.fThrottle), round(controller.fSteer), round(controller.fPitch), round(controller.fYaw), round(controller.fRoll), round(controller.bJump), round(controller.bBoost), round(controller.bHandbrake), ) self.start_time = None self.measurements = [] else: # self.start_time = s.time self.measurements.append((desired_speed, turn_radius)) return sanitize_output_vector(output_vector)
def cell_edges_signed_distance(g,c): vc=g.cells_center()[c] nodes=g.cell_to_nodes(c) L=np.sqrt(g.cells_area()[c]) dists=[] for a,b in utils.circular_pairs(g.nodes['x'][nodes]): ab=b-a ab/=utils.mag(ab) norm=[-ab[1],ab[0]] c_ab=np.dot(vc-a,norm) dists.append( c_ab/L ) return np.array(dists)
def nudge_dual_to_constrained(dual_c,prime_n): dual_ns=g_dual.cell_to_nodes(dual_c) center=g_prime.nodes['x'][prime_n] vecs=g_dual.nodes['x'][dual_ns] - center radii=utils.mag(vecs) mean_r=radii.mean() for n,rad,vec in zip(dual_ns,radii,vecs): print n,rad new_x=center+vec*mean_r/rad g_dual.nodes['x'][n]=new_x g_dual.cells_center(refresh=True,mode='sequential')
def cost(x): g_mod=modified_node_grid(g,n,x) # This one sucked: if 0: cost=np.sum([link_cost(g_mod,j) for j in links]) # mimic report_orthogonality() cost=0 if 1: nsi=4 # quads only right now... centers=g_mod.cells_center(mode='sequential') # this is somehow making the mean and max circumcenter error larger! offsets = g_mod.nodes['x'][g_mod.cells['nodes'][cells,:nsi]] - centers[cells,None,:] dists = utils.mag(offsets) # maybe lets small cells take over too much # cost += np.mean( np.std(dists,axis=1) / np.mean(dists,axis=1) ) # different, but not much better # cost += np.mean( np.std(dists,axis=1) ) base_cost=np.max( np.std(dists,axis=1) ) if verbose: print " Circum. cost: %f"%(base_cost) cost += base_cost if w_area>0 and len(links): # this helps a bit, but sometimes getting good areas # means distorting the shapes A=g_mod.cells_area() pairs=A[ g.edges['cells'][links] ] diffs=(pairs[:,0]-pairs[:,1])/pairs.mean(axis=1) area_cost=w_area*np.sum(diffs**2) if verbose: print " Area cost: %f"%area_cost cost+=area_cost if w_length>0: # if it's not too far off, this makes it look nicer at # the expense of circ. errors l_cost=0 g_mod.update_cell_edges() lengths=g_mod.edges_length() for c in cells: e=g_mod.cell_to_edges(c) if 0: # maybe that's too much leeway, and # the user should have to specify aspect ratios if len(e)==4: a,b,c,d=lengths[e] l_cost+=( ((a-c)/(a+c))**2 + ((b-d)/(b+d))**2 ) else: lmean=lengths.mean() l_cost+= np.sum( (lengths-lmean)**2 ) if verbose: print " Length cost: %f"%( w_length*l_cost ) cost+=w_length*l_cost if w_angle>0: # interior angle of cells deltas=np.diff(g_mod.nodes['x'][triples],axis=1) angles=np.diff( np.arctan2( deltas[:,:,1], deltas[:,:,0] ),axis=1) % (2*np.pi) * 180/np.pi angle_cost=w_angle*np.sum( (angles-90)**2 ) if verbose: print " Angle cost: %f"%angle_cost cost+=angle_cost if w_cangle>0: cangle_cost=0 for c in cells: nodes=g.cell_to_nodes(c) deltas=g_mod.nodes['x'][nodes] - g_mod.cells_center()[c] angles=np.arctan2(deltas[:,1],deltas[:,0]) * 180/np.pi cds=utils.cdiff(angles) % 360. cangle_cost+=np.sum( (cds-90)**4 ) if verbose: print " CAngle cost: %f"%( w_cangle*cangle_cost ) cost+=w_cangle*cangle_cost return cost
def get_output_vector(self, game_tick_packet): my_car = game_tick_packet.gamecars[self.index] player_pos = np.array([ my_car.Location.X, my_car.Location.Y, ]) player_vel = np.array([ my_car.Velocity.X, my_car.Velocity.Y, ]) pitch = URotationToRadians * float(my_car.Rotation.Pitch) yaw = URotationToRadians * float(my_car.Rotation.Yaw) player_facing_dir = np.array([ math.cos(pitch) * math.cos(yaw), math.cos(pitch) * math.sin(yaw) ]) player_right = -clockwise90degrees(player_facing_dir) # score should be positive if going counter clockwise target_pos = np.array([0, 0]) circle_outward = player_pos - target_pos circle_outward_dir = normalize(circle_outward) circle_forward_dir = clockwise90degrees(circle_outward_dir) drifting_score = player_vel.dot(player_right) going_around_target_score = circle_forward_dir.dot(player_vel) score = going_around_target_score * drifting_score steer = controller.fSteer steer = round(steer) # trace(drifting_score) # trace(-steer) # trace(player_pos) circle_facing_dir = np.array([ player_facing_dir.dot(circle_outward_dir), player_facing_dir.dot(circle_forward_dir), ]) # trace(player_facing_dir.dot(circle_forward_dir)) # trace(player_facing_dir.dot(circle_outward_dir)) circle_facing_angle = vec2angle(circle_facing_dir) # 0=outward, tau/4=forward # trace(circle_facing_angle) boost = 1 outward_dist = mag(circle_outward) steer_dist_inner = 400 if boost else 0 steer_dist_outer = 2500 if boost else 1500 should_hard_steer = 1-clamp01((outward_dist - steer_dist_inner) / (steer_dist_outer - steer_dist_inner)) # trace(outward_dist) # trace(should_hard_steer) # trace(outward_dist-steer_dist_inner) desired_angle = lerp(tau*.37, tau*.51, should_hard_steer) if controller.hat_toggle_north: return [ controller.fThrottle, steer, controller.fPitch, controller.fYaw, controller.fRoll, controller.bJump, controller.bBoost, controller.bHandbrake, ] steer = closest180(circle_facing_angle - desired_angle) * 4 turning_rate = my_car.AngularVelocity.Z PID_vel_thingy = 0.8 if boost else 0.5 steer -= PID_vel_thingy * turning_rate # PID loop, essentially return [ 1.0, # fThrottle clamp11(steer), # fSteer 0.0, # fPitch 0.0, # fYaw 0.0, # fRoll 0, # bJump boost, # bBoost 1 # bHandbrake ]
def createPoints(): ## ROUNDED OBTUSE CORNERS # Loop over intersections # On inside of turn, find where entering/exiting lines meet, use point # On outside of turn... # * stop at same length of acute line # * next point is intersection normal, at dist of line width # * subdivide if desired eastPoints = list() eastConstructionLines = list() westPoints = list() westConstructionLines = list() for i in range(len(lineVecs)): #print("\ni = %d" % i) #print("ith Point: %f,%f" % (points[i][0], points[i][1])) prever = i - 2 prev = i - 1 current = i v1 = utils.normalize(lineVecs[prever]) v2 = utils.normalize(lineVecs[prev]) position = v1[0] * v2[1] - v1[1] * v2[0] if (position == 0): print("i=%d, straight ahead" % prever) # ignore points here... let prev vector dictate them continue elif (position > 0): # Left turn, west border is acute p1, p2, p3, p4 = utils.calcParallelLinePoints(halfLineWidth, points[prever], points[prev], points[current], eastSide=False) ## Calculate WEST acute points line1Norm = (lineNormals[prever][0] * halfLineWidth, lineNormals[prever][1] * halfLineWidth) # wX1 = points[prever][0] + line1Norm[0] # wY1 = points[prever][1] + line1Norm[1] # # Vector from current point, into intersection # v1 = (points[prev][0]-points[prever][0], points[prev][1]-points[prever][1]) # # Point on line parallel to line leaving intersection point line2Norm = (lineNormals[prev][0] * halfLineWidth, lineNormals[prev][1] * halfLineWidth) # wX2 = points[current][0] + line2Norm[0] # wY2 = points[current][1] + line2Norm[1] # # Vector from point after intersection, pointing back into it # v2 = (points[prev][0]-points[current][0], points[prev][1]-points[current][1]) # # Gives # p1 = (wX1, wY1) # p2 = (wX1+v1[0], wY1+v1[1]) # # and # p3 = (wX2, wY2) # p4 = (wX2+v2[0], wY2+v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) westPoints.append((xInter, yInter)) westConstructionLines.extend([p1, p2, p3, p4]) ## Calculate EAST obtuse points # Outer corner fans out from point on line fanCentre = points[prev] # Uses point i+1 (i.e. prev) as this process is working out the termination points for the end of the prev vector eX1 = points[prever][0] - line1Norm[0] eY1 = points[prever][1] - line1Norm[1] #drawVector(batch, points[prev], line1Norm) eX2 = points[current][0] - line2Norm[0] eY2 = points[current][1] - line2Norm[1] #drawVector(batch, points[current], line2Norm, (50, 50, 50)) # Gives p1 = (eX1, eY1) # Not required for calculation p2 = (eX1 + v1[0], eY1 + v1[1]) # and p3 = (eX2, eY2) # Not required for calculation p4 = (eX2 + v2[0], eY2 + v2[1]) # 'Cap' is straight line from p2 to p4 capVec = (p4[0] - p2[0], p4[1] - p2[1]) # DRAWS BLUE TO ENTRY #drawLine(fanCentre, p2, (0,0,200)) # DRAWS WHITE TO EXIT #drawLine(fanCentre, p4) # DRAWS BROWN CAP #drawVector(batch, p2, capVec, (120,80,50)) capDist = utils.mag(capVec) capNorm = utils.normalize(capVec) divGap = capDist / (numBevelDivisions + 1) currentDiv = divGap #eastPoints.append(p2) # Temporary increasing colour for diagnosis colourIncrease = int(255 / (numBevelDivisions + 2)) # The +2 is to include the start and end points too for dIndex in range(numBevelDivisions + 2): # t is one minus the increment so triangle fan starts at correct end t = 1 - (1 / (numBevelDivisions + 1)) * dIndex vX = fanCentre[0] - (p2[0] + capVec[0] * t) vY = fanCentre[1] - (p2[1] + capVec[1] * t) # Vector reaches straight line chord, but must be halfLineWidth long normalizedRadius = utils.normalize((vX, vY)) x = fanCentre[0] + normalizedRadius[0] * halfLineWidth y = fanCentre[1] + normalizedRadius[1] * halfLineWidth # Draw diagnostic line for fan radii #print("Radius %d, increasing colour: %d" % (dIndex, colourIncrease)) #drawLine(fanCentre, (x, y), [0, colourIncrease*(dIndex+1), 0]) currentDiv += divGap # Append next fan-point location eastPoints.append((x, y)) if dIndex % 2 == 0 and dIndex != numBevelDivisions: # Append fan centre eastPoints.append(points[prev]) pass else: # Append next fan-point location again to create degenerate triangles eastPoints.append((x, y)) eastConstructionLines.extend([p1, p2]) else: # Right turn, east border is acute ## Calculate EAST acute points # Inverted normal to get normal on east side line1Norm = (lineNormals[prever][0] * halfLineWidth, lineNormals[prever][1] * halfLineWidth) eX1 = points[prever][0] - line1Norm[0] eY1 = points[prever][1] - line1Norm[1] # Vector from current point, into intersection v1 = (points[prev][0] - points[prever][0], points[prev][1] - points[prever][1]) # Point on line parallel to line leaving intersection point line2Norm = (lineNormals[prev][0] * halfLineWidth, lineNormals[prev][1] * halfLineWidth) eX2 = points[current][0] - line2Norm[0] eY2 = points[current][1] - line2Norm[1] # Vector from point after intersection, pointing back into it v2 = (points[prev][0] - points[current][0], points[prev][1] - points[current][1]) # Gives p1 = (eX1, eY1) p2 = (eX1 + v1[0], eY1 + v1[1]) # and p3 = (eX2, eY2) p4 = (eX2 + v2[0], eY2 + v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) eastPoints.append((xInter, yInter)) # Append point on entering line eastPoints.append((xInter + line1Norm[0], yInter + line1Norm[1])) eastPoints.append(points[prev]) # Append a second time to create degenerate triangle eastPoints.append(points[prev]) # Append intersection again eastPoints.append((xInter, yInter)) # Append point on exiting line eastPoints.append((xInter + line2Norm[0], yInter + line2Norm[1])) eastConstructionLines.extend([p1, p2, p3, p4]) ## Calculate WEST obtuse points # Uses point i+1 (i.e. prev) as this process is working out the termination points for the end of the prev vector wX1 = points[prever][0] + line1Norm[0] wY1 = points[prever][1] + line1Norm[1] #drawVector(batch, points[prev], line1Norm) wX2 = points[current][0] + line2Norm[0] wY2 = points[current][1] + line2Norm[1] #drawVector(batch, points[current], line2Norm, (50, 50, 50)) # Gives p1 = (wX1, wY1) p2 = (wX1 + v1[0], wY1 + v1[1]) # and p3 = (wX2, wY2) p4 = (wX2 + v2[0], wY2 + v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) westPoints.append((xInter, yInter)) westConstructionLines.extend([p1, p2]) pass if drawEastMitreConstructionLines: east_acute_construction_vertex_list = batch.add( len(eastConstructionLines), pyglet.gl.GL_LINES, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastConstructionLines))), ('c3B/static', [25, 180, 60] * len(eastConstructionLines))) if drawEastMitrePointLines: east_acute_vertex_list = batch.add( len(eastPoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastPoints))), ('c3B/static', [200, 0, 0] * len(eastPoints))) if drawWestMitreConstructionLines: west_acute_construction_vertex_list = batch.add( len(westConstructionLines), pyglet.gl.GL_LINES, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(westConstructionLines))), ('c3B/static', [25, 180, 60] * len(westConstructionLines))) if drawWestMitrePointLines: west_acute_vertex_list = batch.add( len(westPoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(westPoints))), ('c3B/static', [0, 0, 200] * len(westPoints))) if drawRoundedMitring: #Construct wide-line triangles # # West triangles # westTrianglePoints = list() # for pIndex in range(len(points)): # westTrianglePoints.append(points[pIndex-1]) # westTrianglePoints.append(westPoints[pIndex]) # westTrianglePoints.append(points[-1]) # westTrianglePoints.append(westPoints[0]) # col = list() # for n in range(len(westTrianglePoints)): # col.extend([random.randint(0,255), random.randint(0,255), random.randint(0,255)]) # west_acute_vertex_list = batch.add(len(westTrianglePoints), pyglet.gl.GL_TRIANGLE_STRIP, next(utils.renderGroupGenerator), # ('v2f/static', list(chain.from_iterable(westTrianglePoints))), # ('c3B/static', col) # ) #East triangles uses a deep copy of east points eastTrianglePoints = list(eastPoints) # Add start as end to create loop eastTrianglePoints.append(eastPoints[0]) eastTrianglePoints.append(eastPoints[1]) colLines = list() colTris = list() for n in range(len(eastTrianglePoints)): #col.extend([random.randint(0,255), random.randint(0,255), random.randint(0,255)]) colTris.extend([0.9, 0, 0, 0.5]) colLines.extend([0, 0.2, 0.7, 0.8]) east_acute_tris_list = batch.add( len(eastTrianglePoints), pyglet.gl.GL_TRIANGLE_STRIP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastTrianglePoints))), ('c4f/static', colTris)) east_acute_lines_list = batch.add( len(eastTrianglePoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastTrianglePoints))), ('c4f/static', colLines)) pass
def createPoints(): ## ROUNDED OBTUSE CORNERS # Loop over intersections # On inside of turn, find where entering/exiting lines meet, use point # On outside of turn... # * stop at same length of acute line # * next point is intersection normal, at dist of line width # * subdivide if desired eastPoints = list() eastConstructionLines = list() westPoints = list() westConstructionLines = list() for i in range(len(lineVecs)): #print("\ni = %d" % i) #print("ith Point: %f,%f" % (points[i][0], points[i][1])) prever = i-2 prev = i-1 current = i v1 = utils.normalize(lineVecs[prever]) v2 = utils.normalize(lineVecs[prev]) position = v1[0]*v2[1] - v1[1]*v2[0] if (position == 0): print("i=%d, straight ahead" % prever) # ignore points here... let prev vector dictate them continue elif (position > 0): # Left turn, west border is acute p1, p2, p3, p4 = utils.calcParallelLinePoints(halfLineWidth, points[prever], points[prev], points[current], eastSide=False) ## Calculate WEST acute points line1Norm = (lineNormals[prever][0]*halfLineWidth, lineNormals[prever][1]*halfLineWidth) # wX1 = points[prever][0] + line1Norm[0] # wY1 = points[prever][1] + line1Norm[1] # # Vector from current point, into intersection # v1 = (points[prev][0]-points[prever][0], points[prev][1]-points[prever][1]) # # Point on line parallel to line leaving intersection point line2Norm = (lineNormals[prev][0]*halfLineWidth, lineNormals[prev][1]*halfLineWidth) # wX2 = points[current][0] + line2Norm[0] # wY2 = points[current][1] + line2Norm[1] # # Vector from point after intersection, pointing back into it # v2 = (points[prev][0]-points[current][0], points[prev][1]-points[current][1]) # # Gives # p1 = (wX1, wY1) # p2 = (wX1+v1[0], wY1+v1[1]) # # and # p3 = (wX2, wY2) # p4 = (wX2+v2[0], wY2+v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) westPoints.append((xInter, yInter)) westConstructionLines.extend([p1, p2, p3, p4]) ## Calculate EAST obtuse points # Outer corner fans out from point on line fanCentre = points[prev] # Uses point i+1 (i.e. prev) as this process is working out the termination points for the end of the prev vector eX1 = points[prever][0] - line1Norm[0] eY1 = points[prever][1] - line1Norm[1] #drawVector(batch, points[prev], line1Norm) eX2 = points[current][0] - line2Norm[0] eY2 = points[current][1] - line2Norm[1] #drawVector(batch, points[current], line2Norm, (50, 50, 50)) # Gives p1 = (eX1, eY1) # Not required for calculation p2 = (eX1+v1[0], eY1+v1[1]) # and p3 = (eX2, eY2) # Not required for calculation p4 = (eX2+v2[0], eY2+v2[1]) # 'Cap' is straight line from p2 to p4 capVec = (p4[0]-p2[0], p4[1]-p2[1]) # DRAWS BLUE TO ENTRY #drawLine(fanCentre, p2, (0,0,200)) # DRAWS WHITE TO EXIT #drawLine(fanCentre, p4) # DRAWS BROWN CAP #drawVector(batch, p2, capVec, (120,80,50)) capDist = utils.mag(capVec) capNorm = utils.normalize(capVec) divGap = capDist / (numBevelDivisions+1) currentDiv = divGap #eastPoints.append(p2) # Temporary increasing colour for diagnosis colourIncrease = int(255/(numBevelDivisions+2)) # The +2 is to include the start and end points too for dIndex in range(numBevelDivisions+2): # t is one minus the increment so triangle fan starts at correct end t = 1 - (1/(numBevelDivisions+1))*dIndex vX = fanCentre[0] - (p2[0]+capVec[0]*t) vY = fanCentre[1] - (p2[1]+capVec[1]*t) # Vector reaches straight line chord, but must be halfLineWidth long normalizedRadius = utils.normalize((vX, vY)) x = fanCentre[0] + normalizedRadius[0]*halfLineWidth y = fanCentre[1] + normalizedRadius[1]*halfLineWidth # Draw diagnostic line for fan radii #print("Radius %d, increasing colour: %d" % (dIndex, colourIncrease)) #drawLine(fanCentre, (x, y), [0, colourIncrease*(dIndex+1), 0]) currentDiv += divGap # Append next fan-point location eastPoints.append((x, y)) if dIndex%2 == 0 and dIndex != numBevelDivisions: # Append fan centre eastPoints.append(points[prev]) pass else: # Append next fan-point location again to create degenerate triangles eastPoints.append((x, y)) eastConstructionLines.extend([p1, p2]) else: # Right turn, east border is acute ## Calculate EAST acute points # Inverted normal to get normal on east side line1Norm = (lineNormals[prever][0]*halfLineWidth, lineNormals[prever][1]*halfLineWidth) eX1 = points[prever][0]-line1Norm[0] eY1 = points[prever][1]-line1Norm[1] # Vector from current point, into intersection v1 = (points[prev][0]-points[prever][0], points[prev][1]-points[prever][1]) # Point on line parallel to line leaving intersection point line2Norm = (lineNormals[prev][0]*halfLineWidth, lineNormals[prev][1]*halfLineWidth) eX2 = points[current][0]-line2Norm[0] eY2 = points[current][1]-line2Norm[1] # Vector from point after intersection, pointing back into it v2 = (points[prev][0]-points[current][0], points[prev][1]-points[current][1]) # Gives p1 = (eX1, eY1) p2 = (eX1+v1[0], eY1+v1[1]) # and p3 = (eX2, eY2) p4 = (eX2+v2[0], eY2+v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) eastPoints.append((xInter, yInter)) # Append point on entering line eastPoints.append((xInter+line1Norm[0], yInter+line1Norm[1])) eastPoints.append(points[prev]) # Append a second time to create degenerate triangle eastPoints.append(points[prev]) # Append intersection again eastPoints.append((xInter, yInter)) # Append point on exiting line eastPoints.append((xInter+line2Norm[0], yInter+line2Norm[1])) eastConstructionLines.extend([p1, p2, p3, p4]) ## Calculate WEST obtuse points # Uses point i+1 (i.e. prev) as this process is working out the termination points for the end of the prev vector wX1 = points[prever][0] + line1Norm[0] wY1 = points[prever][1] + line1Norm[1] #drawVector(batch, points[prev], line1Norm) wX2 = points[current][0] + line2Norm[0] wY2 = points[current][1] + line2Norm[1] #drawVector(batch, points[current], line2Norm, (50, 50, 50)) # Gives p1 = (wX1, wY1) p2 = (wX1+v1[0], wY1+v1[1]) # and p3 = (wX2, wY2) p4 = (wX2+v2[0], wY2+v2[1]) xInter, yInter = utils.calcLineIntersection(p1, p2, p3, p4) westPoints.append((xInter, yInter)) westConstructionLines.extend([p1, p2]) pass if drawEastMitreConstructionLines: east_acute_construction_vertex_list = batch.add(len(eastConstructionLines), pyglet.gl.GL_LINES, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastConstructionLines))), ('c3B/static', [25, 180, 60]*len(eastConstructionLines)) ) if drawEastMitrePointLines: east_acute_vertex_list = batch.add(len(eastPoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastPoints))), ('c3B/static', [200, 0, 0]*len(eastPoints)) ) if drawWestMitreConstructionLines: west_acute_construction_vertex_list = batch.add(len(westConstructionLines), pyglet.gl.GL_LINES, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(westConstructionLines))), ('c3B/static', [25, 180, 60]*len(westConstructionLines)) ) if drawWestMitrePointLines: west_acute_vertex_list = batch.add(len(westPoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(westPoints))), ('c3B/static', [0, 0, 200]*len(westPoints)) ) if drawRoundedMitring: #Construct wide-line triangles # # West triangles # westTrianglePoints = list() # for pIndex in range(len(points)): # westTrianglePoints.append(points[pIndex-1]) # westTrianglePoints.append(westPoints[pIndex]) # westTrianglePoints.append(points[-1]) # westTrianglePoints.append(westPoints[0]) # col = list() # for n in range(len(westTrianglePoints)): # col.extend([random.randint(0,255), random.randint(0,255), random.randint(0,255)]) # west_acute_vertex_list = batch.add(len(westTrianglePoints), pyglet.gl.GL_TRIANGLE_STRIP, next(utils.renderGroupGenerator), # ('v2f/static', list(chain.from_iterable(westTrianglePoints))), # ('c3B/static', col) # ) #East triangles uses a deep copy of east points eastTrianglePoints = list(eastPoints) # Add start as end to create loop eastTrianglePoints.append(eastPoints[0]) eastTrianglePoints.append(eastPoints[1]) colLines = list() colTris = list() for n in range(len(eastTrianglePoints)): #col.extend([random.randint(0,255), random.randint(0,255), random.randint(0,255)]) colTris.extend([0.9,0,0,0.5]) colLines.extend([0,0.2,0.7,0.8]) east_acute_tris_list = batch.add(len(eastTrianglePoints), pyglet.gl.GL_TRIANGLE_STRIP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastTrianglePoints))), ('c4f/static', colTris) ) east_acute_lines_list = batch.add(len(eastTrianglePoints), pyglet.gl.GL_LINE_LOOP, next(utils.renderGroupGenerator), ('v2f/static', list(chain.from_iterable(eastTrianglePoints))), ('c4f/static', colLines) ) pass