コード例 #1
0
ファイル: generator.py プロジェクト: fish-face/agutaywusyg
 def get_rect(*args):
     """Get all points in the described rectangle, inclusive"""
     if args == (None,):
         return []
     rect = Rect(args)
     rect.normalize()
     return [(x, y) for x in xrange(rect.x, rect.x+rect.w)
                    for y in xrange(rect.y, rect.y+rect.h)]
コード例 #2
0
ファイル: rect_test.py プロジェクト: CTPUG/pygame_cffi
 def test_normalize( self ):
     r = Rect( 1, 2, -3, -6 )
     r2 = Rect(r)
     r2.normalize()
     self.failUnless( r2.width >= 0 )
     self.failUnless( r2.height >= 0 )
     self.assertEqual( (abs(r.width),abs(r.height)), r2.size )
     self.assertEqual( (-2,-4), r2.topleft )
コード例 #3
0
 def test_normalize(self):
     r = Rect(1, 2, -3, -6)
     r2 = Rect(r)
     r2.normalize()
     self.failUnless(r2.width >= 0)
     self.failUnless(r2.height >= 0)
     self.assertEqual((abs(r.width), abs(r.height)), r2.size)
     self.assertEqual((-2, -4), r2.topleft)
コード例 #4
0
def getLargestRect(points):
    tmpX = sorted(points, key=lambda p: p.x)
    tmpY = sorted(points, key=lambda p: p.y)

    highest = tmpY[-1].y
    lowest = tmpY[0].y
    left = tmpX[-1].x
    right = tmpX[0].x

    tmp = Rect(left, highest, right - left, lowest - highest)
    tmp.normalize()
    return tmp
コード例 #5
0
def calculateIntersectPoint(p1, p2, p3, p4):
	
	p = getIntersectPoint(p1, p2, p3, p4)
	#print p
	
	if p is not None:	
		width = p2[0] - p1[0]
		height = p2[1] - p1[1]       
		r1 = Rect(p1, (width , height))
		r1.normalize()
	
		width = p4[0] - p3[0]
		height = p4[1] - p3[1]
		r2 = Rect(p3, (width, height))
		r2.normalize()	

		# Ensure both rects have a width and height of at least 'tolerance' else the
		# collidepoint check of the Rect class will fail as it doesn't include the bottom
		# and right hand side 'pixels' of the rectangle
		tolerance = 1
		if r1.width < tolerance:
			r1.width = tolerance
					
		if r1.height < tolerance:
			r1.height = tolerance
		
		if r2.width < tolerance:
			r2.width = tolerance
					
		if r2.height < tolerance:
			r2.height = tolerance

		for point in p:	
			try:
				res1 = r1.collidepoint(point)
				res2 = r2.collidepoint(point)
				if res1 and res2:
					point = [int(pp) for pp in point]
					return point
			except:
				# sometimes the value in a point are too large for PyGame's Rect class
				#str = "point was invalid  ", point
				#print str
				pass
				
		# This is the case where the infinately long lines crossed but 
		# the line segments didn't
		return None	
	else:
		return None
コード例 #6
0
class Selection(BaseWidget):
    def __init__(self, x, y):
        self.rect = Rect(x, y, 1, 1)
        self.color = 0, 255, 255
        Renderer.selection = self
        Renderer.on_selection = True

    def on_mouse_motion(self, pos, buttons):
        if buttons[0]:
            self.rect.width = pos[0] - self.rect.x
            self.rect.height = pos[1] - self.rect.y

    def on_mouse_up(self, pos, button):
        Renderer.on_selection = False
        self.rect.normalize()
        return self.rect

    def __repr__(self):
        return 'Selection Object @{},{},{},{}'.format(*self.rect)
コード例 #7
0
def calculateIntersectPoint(p1, p2, p3, p4):
    p = getIntersectPoint(p1, p2, p3, p4)

    if p is not None:
        width = p2[0] - p1[0]
        height = p2[1] - p1[1]
        r1 = Rect(p1, (width, height))
        r1.normalize()

        width = p4[0] - p3[0]
        height = p4[1] - p3[1]
        r2 = Rect(p3, (width, height))
        r2.normalize()

        tolerance = 1
        if r1.width < tolerance:
            r1.width = tolerance

        if r1.height < tolerance:
            r1.height = tolerance

        if r2.width < tolerance:
            r2.width = tolerance

        if r2.height < tolerance:
            r2.height = tolerance

        for point in p:
            try:
                res1 = r1.collidepoint(point)
                res2 = r2.collidepoint(point)
                if res1 and res2:
                    point = [int(pp) for pp in point]
                    return point
            except:
                pass
            return None
        else:
            return None
コード例 #8
0
def calculateIntersectPoint(p1, p2, p3, p4):
  
   p = getIntersectPoint(p1, p2, p3, p4)
  
   if p is not None:               
       width = p2[0] - p1[0]
       height = p2[1] - p1[1]       
       r1 = Rect(p1, (width , height))
       r1.normalize()
      
       width = p4[0] - p3[0]
       height = p4[1] - p3[1]
       r2 = Rect(p3, (width, height))
       r2.normalize()              
 
       # Ensure both rects have a width and height of at least 'tolerance' else the
       # collidepoint check of the Rect class will fail as it doesn't include the bottom
       # and right hand side 'pixels' of the rectangle
       tolerance = 1
       if r1.width &lt; tolerance:
        r1.width = tolerance
                    
       if r1.height &lt; tolerance:
        r1.height = tolerance
コード例 #9
0
ファイル: controller.py プロジェクト: fhorinek/pi8bit
class Controller():
    def __init__(self, canvas, parent):
        self.canvas = canvas
        self.parent = parent

        self.objects = OrderedDict()
        self.objects["LOW"] = Low(self)
        self.objects["HIGH"] = High(self)
        
        self.selected = []
        self.select = False
        self.select_start = False
        self.select_rect = Rect(0, 0, 0, 0)
        
        self.possible_move = False
        
        self.pan = False
        self.pan_x = 0
        self.pan_y = 0
        self.pan_offset_x = 0
        self.pan_offset_y = 0

        self.new_node = False
        self.new_node_direction = NODE_DIR_NA

        self.zoom = 1.0
        self.zoom_step = 0.1
             
        self.obj_id = 0
        self.net_id = 0
        
        self.highlight_mode = LIGHT_NONE
        self.highlight_pos = False
        
        self.add_index = 0
        self.add_list = ["label", "and", "or", "nand", "nor", "xor", "not", "diode", "led", "hex", "tgl", "push", "clk", "input", "output", "memory"]
        
        self.font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_font"] * self.zoom))
        self.label_font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_label_font"] * self.zoom))
        
        self.need_solve_drawable = True
        self.drawable = []
        
        self.read_only = True
        
    def highlight(self, mode, pos = False):
        self.highlight_mode = mode
        self.highlight_pos = pos
        self.canvas.request_io_redraw()
        
    def get_obj_id(self):
        self.obj_id += 1
        return self.obj_id
    
    def get_net_id(self):
        self.net_id += 1
        return self.net_id    
        
    def normalize_positons(self):
        big_rect = False
        for k in self.objects:
            o = self.objects[k]
            if not isinstance(o, Invisible):
                if big_rect:
                    big_rect = big_rect.union(o.rect)
                else:
                    big_rect = o.rect
        
        offset_x = big_rect[0]
        offset_y = big_rect[1]
        
        for k in self.objects:
            o = self.objects[k]
            pos_x = o.rect[0] - offset_x
            pos_y = o.rect[1] - offset_y
            o.set_pos(pos_x, pos_y)
        
        
               
    def write_file(self, filename):
        if self.read_only:
            return
        
        lines = ""
        
        self.normalize_positons()
        
#         print "Writing file", filename
        line_n = 0
        for k in self.objects:
            if k in ["HIGH", "LOW"]:
                continue
            o = self.objects[k]
            
            name = o.name
            fcs = o.fcs
            p = o.get_params()
            if p == False:
                continue
            params = " ".join(p)
            line = "\t".join([name, fcs, params])
            lines += "%s\n" % line

#             print " %5d: %s" % (line_n, line)  
            line_n += 1
        
        f = open(filename, "w")
        f.write(lines)
        f.close() 
#         print "done", filename
        
    def read_file(self, filename):
        print "Reading file", filename
        
        try:        
            f = open(filename, "r")
            data = f.readlines()
            f.close()
            
            self.create_objects(data)
    
            print "done", filename
            return True
        except IOError as e:
            print "not found", e
            return False
        
    def create_objects(self, data):
        params = OrderedDict()
        line_n = 0

        for line in data:
            line_n += 1 
            
            arr = line.split()
            
            print " %5d: %s" % (line_n, " ".join(arr))
            
            if (len(arr) < 2):
                continue
            
            name = arr[0]
            fcs = arr[1]
            
            #calc obj id
            s = name.split("_")
            if len(s) == 4 and s[0] == "" and s[1] == "":
                try:
                    obj_id = int(s[3])
                    self.obj_id = max(obj_id + 1, self.obj_id)
                except ValueError:
                    pass

            #calc net id
            if fcs == "node":
                s = arr[3].split("_")
                if len(s) == 4 and s[0] == "" and s[1] == "":
                    try:
                        net_id = int(s[3])
                        self.net_id = max(net_id + 1, self.net_id)
                    except ValueError:
                        pass
            
            o = False
            if fcs in self.canvas.cells:
                o = self.canvas.cells[fcs](self)
             
            if (o is not False):
                params[name] = arr
                self.objects[name] = o
        
        #let object to parse parameters
        for name in params:
            arr = params[name]

            o = self.objects[name]
            o.parse(arr)   
            
    def find_cell(self, name):
        if name in self.objects:
            return self.objects[name]
        else:
            return False           
            
    def find_cell_pin(self, name):
        arr = name.split(".")
        if (len(arr) == 1):
            o_name = arr[0]
            o_pin = False
        else:
            o_name, o_pin = arr
        
        o = self.find_cell(o_name)
        if o == False:
            print name, "not found!"
            return False
        
        if o_pin == False:
            if len(o.outputs) > 0:
                o_pin = o.outputs[0]
            else:
                o_pin = False
        
        return o, o_pin  
    
    def find_output(self, obj, pin):
        for k in self.objects:
            o = self.objects[k]
            for p in o.inputs:
                pair = o.inputs[p]
                if pair == False:
                    continue
                if pair[0] == obj and pair[1] == pin:
                    return o, p
        return False
    
    def blit(self, surface, rect):
        rect = Rect(rect)
        rect.x += self.pan_offset_x
        rect.y += self.pan_offset_y
        rect.x *= self.zoom
        rect.y *= self.zoom
        
        self.canvas.screen.blit(surface, rect)
        
    def draw_circle(self, pos, state):
        pos = list(pos)
        pos[0] += self.pan_offset_x
        pos[1] += self.pan_offset_y        
        pos = [int(x * self.zoom) for x in pos] 
        if (state):
            color = self.canvas.style["c_high"]
        else:
            color = self.canvas.style["c_low"]

        self.canvas.draw_circle(color, pos, self.zoom) 
        
    def draw_line(self, start, end, state):     
        #copy the data
        start = list(start)
        end = list(end)
        
        start[0] += self.pan_offset_x
        start[1] += self.pan_offset_y
        end[0] += self.pan_offset_x
        end[1] += self.pan_offset_y

        start =  [int(x * self.zoom) for x in start] 
        end = [int(x * self.zoom) for x in end] 

        if state:
            color = self.canvas.style["c_high"]
        else:
            color = self.canvas.style["c_low"]   
            
        self.canvas.draw_line(start, end, color, self.zoom)
        
    def draw_rect(self, surface, color, rect, width = 0):
        rect = Rect(rect)
        w = int(width * self.zoom)
        rect = Rect([int(x * self.zoom) for x in rect]) 
        if width > 0 and w == 0:
            w = 1
        pygame.draw.rect(surface, color, rect, w)
        
    def draw_text(self, surface, text, rect):
        tmp = self.font.render(text, True, self.canvas.style["c_text"])
        rect2 = tmp.get_rect()
        rect = Rect([int(x * self.zoom) for x in rect]) 
        rect = [rect.x + rect.w / 2 - rect2.w / 2, rect.y + rect.h / 2 - rect2.h / 2]
        
        surface.blit(tmp,  rect)        
        
    def draw_label(self, text, rect):
        tmp = self.label_font.render(text, True, self.canvas.style["c_label"])
        rect2 = tmp.get_rect()
        rect = Rect([int(x * self.zoom) for x in rect]) 
        rect = [rect.x + rect.w / 2 - rect2.w / 2, rect.y + rect.h / 2 - rect2.h / 2]
        
        return tmp
        
    def label_font_size(self, text):
        label_font = pygame.font.Font(pygame.font.get_default_font(), self.canvas.style["d_label_font"])
        tmp = label_font.render(text, True, self.canvas.style["c_text"])
        rect2 = tmp.get_rect()

        return rect2
        
    def draw_highlight(self):
        if self.highlight_mode == LIGHT_LINE:
            start = list(self.highlight_pos[0])
            end = list(self.highlight_pos[1])
            
            width = self.canvas.style["d_line_height"]
            w = int(width * self.zoom)
            
            start[0] += self.pan_offset_x
            start[1] += self.pan_offset_y
            start = [int(x * self.zoom) for x in start] 
            
            end[0] += self.pan_offset_x
            end[1] += self.pan_offset_y
            end = [int(x * self.zoom) for x in end] 
            
            if width > 0 and w == 0:
                w = 1
            pygame.draw.line(self.canvas.screen, self.canvas.style["c_highlight"], start, end, w)        

        if self.highlight_mode == LIGHT_POINT:
            width = self.canvas.style["d_point"]
            w = int(width * self.zoom)
            
            point = list(self.highlight_pos)
            point[0] += int(self.pan_offset_x)
            point[1] += int(self.pan_offset_y)
            point = [int(x * self.zoom) for x in point] 
            
            if width > 0 and w == 0:
                w = 1
            pygame.draw.circle(self.canvas.screen, self.canvas.style["c_highlight"], point, w)        
        
    def draw_highlight_box(self, rect):
        rect = Rect(rect)
        width = self.canvas.style["d_line_height"]
        w = int(width * self.zoom)
        rect.x += self.pan_offset_x
        rect.y += self.pan_offset_y
        rect = Rect([int(x * self.zoom) for x in rect]) 
        if width > 0 and w == 0:
            w = 1
        pygame.draw.rect(self.canvas.screen, self.canvas.style["c_highlight"], rect, w)
        
    def mk_surface(self, rect):
        size = [int(rect.w * self.zoom), int(rect.h * self.zoom)]
        return pygame.Surface(size, self.canvas.surface_flags)
        
    def update_zoom(self):
        self.font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_font"] * self.zoom))
        self.label_font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_label_font"] * self.zoom))

        self.solve_drawable()

        for k in self.objects:
            self.objects[k].request_update_body()
              
        if self.canvas.mode == MODE_ADD:
            self.new_node.request_update_body()
            
        self.canvas.request_redraw()
        
    def request_redraw(self):
        for o in self.drawable:
            o.request_redraw()     
        
    def solve_drawable(self):
        self.need_solve_drawable = True
                
    def draw(self, mode):

        if self.need_solve_drawable:
            self.need_solve_drawable = False
            window = Rect(-self.pan_offset_x, -self.pan_offset_y, self.canvas.size[0] / self.zoom, self.canvas.size[1] / self.zoom)
            self.drawable = []
            
            for k in self.objects:
                self.objects[k].solve_drawable(window, self.drawable)      
        
        if mode == MODE_SELECT:
            self.canvas.request_redraw()
            self.canvas.request_io_redraw()
        
        for o in self.drawable:
            o.draw()
            o.draw_io()
       
        if mode == MODE_SELECT:
            self.select_rect.normalize()
            self.draw_highlight_box(self.select_rect)
        
        for o in self.selected:
            self.draw_highlight_box(o.rect)

        if mode == MODE_WIRE:            
            self.draw_highlight()
            
        if mode in [MODE_ADD, MODE_ADD_MODULE]:
            if self.new_node is not False:
                self.new_node.draw()
                self.new_node.draw_io()
        
    def tick(self):
        for k in self.objects:
            self.objects[k].tick()        
         
    def reset(self):
        for k in self.objects:
            self.objects[k].reset()     
            
    def request_update(self): pass
            
    def clear_io_cache(self):
        for o in self.drawable:
            o.clear_io_cache()              
            
    def get_object_pos(self, pos, exclude = []):
        pos = list(pos)
        
        object_list = list(self.drawable)
        object_list.reverse()
        
        for o in object_list:
            if o in exclude:
                continue               
            if (o.rect.collidepoint(pos)):
                return o
        return False        
    
    #wire form input / output
    def get_line_pos(self, pos, exclude = []):
        pos = list(pos)
        
        for o in self.drawable:
            if o in exclude:
                continue
            
            data = o.check_input_line_collision(pos)
            if (data):
                if data[2] in exclude:
                    continue
                return data
        return False   
    
    #wire form net
    def get_net_line_pos(self, pos, exclude=[]):
        pos = list(pos)
        
        for o in self.drawable:
            if isinstance(o, wire.Node):
                if o in exclude:
                    continue
                
                data = o.check_net_line_collision(pos)
                if (data):
                    if data[1] in exclude:
                        continue
                    
                    return data
        return False  
    
    def get_output_pos(self, pos, exclude=[]):
        pos = list(pos)

        for o in self.drawable:
            if o in exclude:
                continue            
            
            pin = o.check_output_collision(pos)
            if (pin):
                return o, pin
        return False   
   
    def get_input_pos(self, pos, exclude=[]):
        pos = list(pos)
        
        for o in self.drawable:
            if o in exclude:
                continue               
            pin = o.check_input_collision(pos)
            if (pin):
                return o, pin
        return False     
            
        
    def add_object(self, fcs, pos, params = []):
        o = self.canvas.cells[fcs](self)
        name = "__%s_%d" % (fcs, self.get_obj_id())
        self.objects[name] = o
        o.update()
        o.middle_offset()
        pos = "%dx%d" % (pos[0], pos[1])
        o.parse([name, fcs, pos] + params)
        self.request_redraw()
        self.solve_drawable()
        return o     

    def add_node(self, pos, net = False):
        o = self.canvas.cells["node"](self)
        name = "__node_%d" % (self.get_obj_id())
        self.objects[name] = o
        o.update()
        o.middle_offset()
        pos = "%dx%d" % (pos[0], pos[1])
        if net is False:
            net = self.add_net()
        o.parse([name, "node", pos, net.name])
        self.request_redraw()
        self.solve_drawable()
        return o     
    
    def add_net(self, net_name = False):
        if net_name is False:
            net_name = "__net_%d" % (self.get_net_id())
            
        o = self.canvas.cells["net"](self)
        self.objects[net_name] = o
        o.parse([net_name, "net"])
        
        return o
           
    def apply_grid(self, obj):
        g_hor = self.canvas.style["g_hor"]
        g_ver = self.canvas.style["g_ver"]        
        obj.rect.x = int(round(obj.rect.x / float(g_hor)) * g_hor)
        obj.rect.y = int(round(obj.rect.y / float(g_ver)) * g_ver)
        obj.clear_offset()
        obj.update_io_xy()
        
    def delete(self, name):
        if name in self.objects:
            self.objects[name].disconnect()
            del self.objects[name]
            self.canvas.request_redraw()
            self.solve_drawable()
            
    def select_obj(self, objs):
        for o in objs:
            if o not in self.selected and not isinstance(o, Invisible):
                self.selected.append(o)
                #self.canvas.request_io_redraw()
                
    def deselect_obj(self, objs):
        for o in objs:
            if o in self.selected:
                self.selected.remove(o)
                self.canvas.request_redraw()
    
    def tglselect_obj(self, obj):
        if obj in self.selected:
            self.deselect_obj([obj])
        else:
            self.select_obj([obj])
                        
    def clear_selection(self):
        self.selected = []
        #self.canvas.request_io_redraw()                
            
    def rename_obj(self, obj, new_name):
        if new_name in self.objects:
            return False
        
        del self.objects[obj.name]
        obj.name = new_name
        self.objects[new_name] = obj
        obj.update()
        
        return True
            
    def event(self, event, mode):
        
        #GET event info
        hover_object = False
        keys = pygame.key.get_pressed()
        
        if hasattr(event, "pos"):
            mouse_x = (event.pos[0] / self.zoom) - self.pan_offset_x
            mouse_y = (event.pos[1] / self.zoom) - self.pan_offset_y
            
            hover_object = self.get_object_pos([mouse_x, mouse_y])
            
            if keys[pygame.K_LCTRL]:
                g_hor = self.canvas.style["g_hor"]
                g_ver = self.canvas.style["g_ver"]        
                mouse_x = int(round(mouse_x / float(g_hor)) * g_hor)
                mouse_y = int(round(mouse_y / float(g_ver)) * g_ver)
        
        if event.type == pygame.KEYDOWN:
            if event.key == ord('a') and self.canvas.mode == MODE_EDIT:
                fcs = self.add_list[self.add_index]
                pos = "%dx%d" % (0, 0)
                name = "_%s_" % fcs
                self.new_node = self.canvas.cells[fcs](self)
                self.new_node.update()
                self.new_node.middle_offset()
                self.new_node.parse([name, fcs, pos])
                self.canvas.set_mode(MODE_ADD)        
                   
            if event.key == ord('m') and self.canvas.mode == MODE_EDIT:
                self.canvas.set_mode(MODE_ADD_MODULE)    
                       
            if event.key == ord('e') and self.canvas.mode in [MODE_IDLE, MODE_WIRE, MODE_RENAME]:
                self.highlight(LIGHT_NONE)
                self.canvas.set_mode(MODE_EDIT)  
                
            if event.key == ord('d') and self.canvas.mode == MODE_IDLE:
                self.canvas.set_mode(MODE_STEP)    
                              
            if event.key == ord('w') and self.canvas.mode == MODE_EDIT:
                self.canvas.set_mode(MODE_WIRE)  
                 
            if event.key == ord('r') and self.canvas.mode == MODE_EDIT:
                self.canvas.set_mode(MODE_RENAME)     
                              
            if event.key == ord('s'):
                self.read_only = not self.read_only
                self.canvas.request_redraw()     
                 
            if event.key == pygame.K_SPACE and self.canvas.mode == MODE_STEP:
                self.tick()
                                 
            if event.key == pygame.K_ESCAPE:
                self.canvas.request_io_redraw()
                if self.canvas.mode == MODE_STEP:                                   
                    self.canvas.set_mode(MODE_IDLE)                   
                
                if self.canvas.mode == MODE_EDIT:                                   
                    self.clear_selection()
                    self.canvas.set_mode(MODE_IDLE)   
                    
                if self.canvas.mode == MODE_WIRE:
                    self.canvas.set_mode(MODE_EDIT)   
                    self.highlight(LIGHT_NONE)

                if self.canvas.mode == MODE_ADD:
                    self.canvas.set_mode(MODE_EDIT)   
                    self.new_node = False

                if self.canvas.mode == MODE_ADD_MODULE:
                    self.canvas.set_mode(MODE_EDIT)   
                    self.new_node = False
                    
                if self.canvas.mode == MODE_RENAME:                                   
                    self.canvas.set_mode(MODE_EDIT)          
        
        #PAN is woring allways
        #RIGHT DOWN => START PAN
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == MID:
            self.pan_x = event.pos[0] / self.zoom
            self.pan_y = event.pos[1] / self.zoom
            self.pan = True
            self.mode_before = mode
            self.canvas.set_mode(MODE_PAN)
        
        if self.pan:
            #RIGHT UP => STOP PAN
            if event.type == pygame.MOUSEBUTTONUP and event.button == MID:
                self.pan_offset_x += event.pos[0] / self.zoom - self.pan_x
                self.pan_offset_y += event.pos[1] / self.zoom - self.pan_y
                self.solve_drawable()
                self.canvas.request_redraw()
                self.pan = False
                self.canvas.set_mode(self.mode_before)
            
            if event.type == pygame.MOUSEMOTION:
                self.pan_offset_x += event.pos[0] / self.zoom - self.pan_x
                self.pan_offset_y += event.pos[1] / self.zoom - self.pan_y     
                self.pan_x = event.pos[0] / self.zoom
                self.pan_y = event.pos[1] / self.zoom
                
                self.solve_drawable()
                self.canvas.request_redraw()
      
            
        #ZOOM is working allways
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == WHEEL_UP:  
            if self.zoom < 1.5:
                             
                self.pan_offset_x -= mouse_x + self.pan_offset_x - event.pos[0] / self.zoom
                self.pan_offset_y -= mouse_y + self.pan_offset_y - event.pos[1] / self.zoom
                
                pan_x = event.pos[0] / self.zoom
                pan_y = event.pos[1] / self.zoom    
                
                self.zoom += self.zoom_step                 

                self.pan_offset_x += event.pos[0] / self.zoom - pan_x
                self.pan_offset_y += event.pos[1] / self.zoom - pan_y
       
                self.update_zoom()

        if event.type == pygame.MOUSEBUTTONDOWN and event.button == WHEEL_DOWN:   
            if self.zoom > 0.2:
                
                pan_x = event.pos[0] / self.zoom
                pan_y = event.pos[1] / self.zoom    
                            
                self.zoom -= self.zoom_step

                self.pan_offset_x += event.pos[0] / self.zoom - pan_x
                self.pan_offset_y += event.pos[1] / self.zoom - pan_y
                           
                self.update_zoom()
          
        if mode == MODE_IDLE or mode == MODE_STEP:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                if hover_object is not False:
                    hover_object.click()
        
        if mode == MODE_RENAME:
            #LEFT DOWN => RENAME
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                if hover_object is not False:
                    if isinstance(hover_object, cell.Label):
                        label = utils.gui_textedit("Change the label", hover_object.label)
                        if len(label) == 0:
                            utils.gui_alert("Error", "Labels can't be empty")
                        else:
                            hover_object.label = label
                            hover_object.update()
                            self.canvas.set_mode(MODE_EDIT)
                    else:
                        if isinstance(hover_object, wire.Node):
                            obj = hover_object.net
                        else:
                            obj = hover_object
                        
                        old_name = obj.name    
                        name = utils.gui_textedit("Rename the object", obj.name)
                        if old_name == name:
                            return
                        
                        if len(name) == 0:
                            utils.gui_alert("Error", "Name can't be empty")
                            return
                        
                        if not self.rename_obj(obj, name):
                            utils.gui_alert("Error", "Unable to rename object")
                        else:
                            self.canvas.set_mode(MODE_EDIT)    
                        
              
            
        if mode == MODE_EDIT:
            #LEFT DOWN => START SELECT
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                if hover_object is False:
                    #SHIFT prevent clear selection
                    if not keys[pygame.K_LSHIFT]:
                        self.clear_selection()  
                        
                    self.canvas.set_mode(MODE_SELECT)  
                    self.select_start = [mouse_x, mouse_y]
                    self.select_rect = pygame.Rect(mouse_x, mouse_y, 0, 0)
                else:
                    if keys[pygame.K_LSHIFT]:
                        self.tglselect_obj(hover_object)
                    else:
                        if hover_object not in self.selected:
                            self.clear_selection()
                            self.select_obj([hover_object])
                    
                    if hover_object in self.selected:    
                        self.possible_move = True       
         
            if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
                if self.possible_move is True:
                    self.possible_move = False
         
            if event.type == pygame.MOUSEMOTION:
                if self.possible_move is True:
                    self.possible_move = False
                    for o in self.selected:
                        o.set_offset(mouse_x - o.rect[0], mouse_y - o.rect[1])
                        
                    self.canvas.set_mode(MODE_MOVE)
                    
            if event.type == pygame.KEYDOWN and event.key == pygame.K_DELETE:
                for o in self.selected:
                    self.delete(o.name)
                self.clear_selection()
                
                                       
        if mode == MODE_SELECT:
            if event.type == pygame.MOUSEMOTION:
                w = mouse_x - self.select_start[0]
                h = mouse_y - self.select_start[1]
                self.select_rect = pygame.Rect(self.select_start[0], self.select_start[1], w, h)

            if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
                self.canvas.request_io_redraw()
                for k in self.objects:
                    o = self.objects[k]
                    if (self.select_rect.colliderect(o.rect)):
                        self.select_obj([o])
                self.canvas.set_mode(MODE_EDIT);

        if mode == MODE_MOVE:           
            if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
                self.canvas.request_redraw()
                for o in self.selected:
                    o.set_pos(mouse_x, mouse_y)
                    self.apply_grid(o)
                
                if (len(self.selected) == 1):
                    self.clear_selection()
                    
                self.canvas.set_mode(MODE_EDIT);
        
            if event.type == pygame.MOUSEMOTION:
                self.canvas.request_redraw()
                for o in self.selected:
                    o.set_pos(mouse_x, mouse_y)

        if mode == MODE_WIRE:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                print 
                print "<<"
                
                print "get_object_pos", hover_object
                if isinstance(hover_object, wire.Node):
                    self.new_node = self.add_node([mouse_x, mouse_y], hover_object.net)
                    self.new_node.add_sibling(hover_object)

                    self.new_node_direction = NODE_DIR_FROM_NODE
                    self.solve_drawable()
                    return                
                
                target = self.get_input_pos([mouse_x, mouse_y])
                print "get_input_pos", target
                if target is not False:
                    obj, pin = target
                    self.new_node = self.add_node([mouse_x, mouse_y])
                    obj.assign_input(pin, self.new_node, "Y")
                    self.new_node_direction = NODE_DIR_FROM_INPUT
                    self.solve_drawable()
                    return
                
                target = self.get_output_pos([mouse_x, mouse_y])
                print "get_output_pos", target
                if target is not False:
                    obj, pin = target
                    self.new_node = self.add_node([mouse_x, mouse_y])
                    self.new_node.assign_free_input(obj, pin)
                    self.new_node_direction = NODE_DIR_FROM_OUTPUT
                    self.solve_drawable()
                    return                   
                
                target = self.get_line_pos([mouse_x, mouse_y])
                print "get_line_pos", target
                if target is not False:
                    obj, obj_pin, inp, inp_pin = target
                    start_node = self.add_node([mouse_x, mouse_y])
                    self.apply_grid(start_node)
                    
                    if isinstance(inp, wire.Node):
                        inp.add_sibling(start_node)
                        start_node.net.remove_node(self.new_node)
                        self.delete(start_node.net.name)
                        inp.net.add_node(start_node)
                    obj.assign_input(obj_pin, start_node, "Y")
                        
                    if isinstance(obj, wire.Node):
                        obj.add_sibling(start_node)
                        start_node.net.remove_node(start_node)
                        self.delete(start_node.net.name)
                        obj.net.add_node(start_node)
                    start_node.assign_free_input(inp, inp_pin)        

                    self.new_node = self.add_node([mouse_x, mouse_y], start_node.net)
                    self.new_node.add_sibling(start_node)      
                    
                    self.new_node_direction = NODE_DIR_FROM_NODE
                    self.solve_drawable()
                    return                   
                
                target = self.get_net_line_pos([mouse_x, mouse_y])
                print "get_net_line_pos", target
                if target is not False:
                    node1, node2, net = target
                    start_node = self.add_node([mouse_x, mouse_y], net)
                    self.apply_grid(start_node)                        
                    node1.remove_sibling(node2)
                    node1.add_sibling(start_node)
                    node2.remove_sibling(node1)
                    node2.add_sibling(start_node)
                    
                    self.new_node = self.add_node([mouse_x, mouse_y], start_node.net)
                    self.new_node.add_sibling(start_node)      
                    
                    self.new_node_direction = NODE_DIR_FROM_NODE
                    self.solve_drawable()
                    return     
  
                else:
                    if hover_object is False: 
                        start_node = self.add_node([mouse_x, mouse_y])
                        self.apply_grid(start_node)
                        
                        self.new_node = self.add_node([mouse_x, mouse_y], start_node.net)
                        self.new_node.add_sibling(start_node)      
                        self.new_node_direction = NODE_DIR_FROM_NODE
                        self.solve_drawable()
            
            if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
                if self.new_node is not False:
                    self.new_node.set_pos(mouse_x, mouse_y)
                    self.apply_grid(self.new_node)

                    print 
                    print ">>"

                    target = self.get_object_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_object_pos", target
                    if target is not False:
                        if isinstance(target, wire.Node):
                            #FROM_INPUT / FROM_OUTPUT will be handeled lower
                            if self.new_node_direction == NODE_DIR_FROM_NODE:
                                prev = self.new_node.siblings[0]
                                target.add_sibling(prev)
                                prev.net.asimilate(target.net)

                                self.delete(self.new_node.name)
                                self.new_node = False
                                self.solve_drawable()
                                return
                    
                    target = self.get_input_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_input_pos", target
                    if target is not False and self.new_node_direction is not NODE_DIR_FROM_INPUT:
                        obj, pin = target
                        if self.new_node_direction == NODE_DIR_FROM_NODE:
                            obj.assign_input(pin, self.new_node.siblings[0], "Y")
                        if self.new_node_direction == NODE_DIR_FROM_OUTPUT:
                            key = self.new_node.inputs.keys()[0]
                            inp, inp_pin = self.new_node.inputs[key]
                            obj.assign_input(pin, inp, inp_pin)
                        
                        self.delete(self.new_node.name)
                        self.new_node = False
                        self.solve_drawable()
                        return
                    
                    target = self.get_output_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_output_pos", target
                    if target is not False and self.new_node_direction is not NODE_DIR_FROM_OUTPUT:
                        obj, pin = target
                        if self.new_node_direction == NODE_DIR_FROM_NODE:
                            self.new_node.siblings[0].assign_free_input(obj , pin)
                        if self.new_node_direction == NODE_DIR_FROM_INPUT:
                            orig_obj, orig_pin = self.find_output(self.new_node, "Y")
                            orig_obj.assign_input(orig_pin, obj, pin)
                                
                        self.delete(self.new_node.name)
                        self.new_node = False
                        self.solve_drawable()
                        return                    
                    
                    target = self.get_line_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_line_pos", target
                    if target is not False:
                        obj, obj_pin, inp, inp_pin = target
                        if isinstance(inp, wire.Node):
                            inp.add_sibling(self.new_node)
                            self.new_node.net.asimilate(inp.net)
                        else:
                            self.new_node.assign_free_input(inp , inp_pin)
                            
                        if isinstance(obj, wire.Node):
                            obj.add_sibling(self.new_node)
                            obj.clear_input(obj_pin)
                            self.new_node.net.asimilate(obj.net)
                        else:
                            obj.assign_input(obj_pin, self.new_node, "Y")        
                            
                        self.new_node = False
                        self.solve_drawable()
                        return        

                    target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_net_line_pos", target
                    if target is not False:
                        node1, node2, net = target
                        node1.remove_sibling(node2)
                        node1.add_sibling(self.new_node)
                        node2.remove_sibling(node1)
                        node2.add_sibling(self.new_node)
                        self.new_node.net.asimilate(net)
                        self.new_node = False
                        self.solve_drawable()
                        return        

                    self.new_node = False
                    self.canvas.request_redraw()
                               
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT:
                if self.new_node is not False:
                    self.delete(self.new_node.name)
                    self.new_node = False
                else:
                    #delete node or split siblings or net
                    if isinstance(hover_object, wire.Node):
                        siblings = hover_object.net.list_node_sibling(hover_object)
                        if len(siblings) > 0:
                            successor = siblings[0]
                            
                            for node in siblings:
                                successor.add_sibling(node)
                                
                            for k in hover_object.inputs:
                                print "hover_object.input", k, hover_object, hover_object.inputs
                                obj, pin = hover_object.inputs[k]
                                successor.assign_free_input(obj, pin)
                                
                            target = self.find_output(hover_object, "Y")
                            while target is not False:
                                obj, pin = target
                                obj.assign_input(pin, successor, "Y")
                                target = self.find_output(hover_object, "Y")
                        
                        self.delete(hover_object.name)
                        self.highlight(LIGHT_NONE)
                        self.solve_drawable()
                        return
                    
                    target = self.get_line_pos([mouse_x, mouse_y])
                    print "get_line_pos", target
                    if target is not False:
                        obj, obj_pin, inp, inp_pin = target
                        obj.clear_input(obj_pin)
                        self.highlight(LIGHT_NONE)
                        self.solve_drawable()
                        self.canvas.request_redraw()
                        return                  
                    
                    target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node])
                    print "get_net_line_pos", target
                    if target is not False:
                        node1, node2, net = target
                        node1.remove_sibling(node2)
                        node2.remove_sibling(node1)
                        net.rebuild()
                        self.canvas.request_redraw()
                        self.highlight(LIGHT_NONE)
                        self.solve_drawable()
                        return     

            if event.type == pygame.MOUSEMOTION:
                if self.new_node is not False:
                    self.new_node.set_pos(mouse_x, mouse_y)
                    self.canvas.request_redraw()

                target = self.get_object_pos([mouse_x, mouse_y], [self.new_node])
#                 print "get_object_pos", target
                if target is not False:
                    if isinstance(target, wire.Node):
                        self.highlight(LIGHT_POINT, target.output_xy["Y"]);
                        return
                
                target = self.get_input_pos([mouse_x, mouse_y], [self.new_node])
#                 print "get_input_pos", target
                if target is not False:
                    obj, pin = target
                    pos = obj.input_xy[pin]
                    self.highlight(LIGHT_POINT, pos);
                    return
                
                target = self.get_output_pos([mouse_x, mouse_y], [self.new_node])
#                 print "get_output_pos", target
                if target is not False:
                    obj, pin = target
                    pos = obj.output_xy[pin]
                    self.highlight(LIGHT_POINT, pos);
                    return                    
                
                target = self.get_line_pos([mouse_x, mouse_y], [self.new_node])
#                 print "get_line_pos", target
                if target is not False:
                    obj, obj_pin, inp, inp_pin = target
                    
                    if isinstance(obj, wire.Node):
                        start = obj.output_xy["Y"]
                    else:
                        start = obj.input_xy[obj_pin]
                        
                    if isinstance(inp, wire.Node):
                        end = inp.output_xy["Y"]
                    else:                            
                        end = inp.output_xy[inp_pin]
                    
                    self.highlight(LIGHT_LINE, [start, end])
                    return        

                target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node])
#                 print "get_net_line_pos", target
                if target is not False:
                    node1, node2, net = target
                    start = node1.output_xy["Y"]
                    end = node2.output_xy["Y"]
                    self.highlight(LIGHT_LINE, [start, end])
                    return        

                self.highlight(LIGHT_NONE)
                
        if mode == MODE_ADD:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT:
                self.add_index = (self.add_index + 1) % len(self.add_list)
                fcs = self.add_list[self.add_index]
                pos = "%dx%d" % (mouse_x, mouse_y)
                name = "_%s_" % fcs
                self.new_node = self.canvas.cells[fcs](self)
                self.new_node.update()
                self.new_node.middle_offset()
                self.new_node.parse([name, fcs, pos])
                self.new_node.drawable = True
                self.canvas.request_redraw()
                                
            if event.type == pygame.MOUSEMOTION:
                if self.new_node is not False:
                    self.new_node.set_pos(mouse_x, mouse_y)
                    self.new_node.clear_io_cache()
                    self.canvas.request_redraw()
            
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                o = self.add_object(self.add_list[self.add_index], [mouse_x, mouse_y])
                self.apply_grid(o)
                
        if mode == MODE_ADD_MODULE:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT:
                fcs = "module"
                pos = "%dx%d" % (mouse_x, mouse_y)
                name = "_%s_" % fcs
                self.new_node = self.canvas.cells[fcs](self)
                self.new_node.update()
                self.new_node.middle_offset()
                self.new_node.parse([name, fcs, pos])
                self.new_node_filename = self.new_node.filename
                self.new_node.drawable = True
                self.canvas.request_redraw()
            
            if event.type == pygame.MOUSEMOTION:
                if self.new_node is not False:
                    self.new_node.set_pos(mouse_x, mouse_y)
                    self.new_node.clear_io_cache()
                    self.canvas.request_redraw()
            
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT:
                o = self.add_object("module", [mouse_x, mouse_y], [self.new_node_filename])
                self.apply_grid(o)                
                
                
コード例 #10
0
def intersection_pt(p1, p2, p3, p4):
  
	p = getIntersectPoint(p1, p2, p3, p4)
  
	if p is not None:               
		width = p2[0] - p1[0]
		height = p2[1] - p1[1]       
		r1 = Rect(p1, (width , height))
		r1.normalize()

		width = p4[0] - p3[0]
		height = p4[1] - p3[1]
		r2 = Rect(p3, (width, height))
		r2.normalize()              
 
	   # Ensure both rects have a width and height of at least 'tolerance' else the
	   # collidepoint check of the Rect class will fail as it doesn't include the bottom
	   # and right hand side 'pixels' of the rectangle
		tolerance = 1
		if r1.width <tolerance:
			r1.width = tolerance
					
		if r1.height <tolerance:
			r1.height = tolerance
		
		if r2.width <tolerance:
			r2.width = tolerance
					
		if r2.height <tolerance:
			r2.height = tolerance
 
		for point in p:                 
			try:    
				res1 = r1.collidepoint(point)
				res2 = r2.collidepoint(point)
				if res1 and res2:
					point = [int(pp) for pp in point]                                
					return point
			except:
				# sometimes the value in a point are too large for PyGame's Rect class
				str = "point was invalid  ", point                
				print str
				
		# This is the case where the infinately long lines crossed but 
		# the line segments didn't
		return None            
	
	else:
		return None
		
		
# # Test script below...
# if __name__ == "__main__":
 
# 	# line 1 and 2 cross, 1 and 3 don't but would if extended, 2 and 3 are parallel
# 	# line 5 is horizontal, line 4 is vertical
# 	p1 = (1,5)
# 	p2 = (4,7)
	
# 	p3 = (4,5)
# 	p4 = (3,7)
	
# 	p5 = (4,1)
# 	p6 = (3,3)
	
# 	p7 = (3,1)
# 	p8 = (3,10)
	
# 	p9 =  (0,6)
# 	p10 = (5,6)
	
# 	p11 = (472.0, 116.0)
# 	p12 = (542.0, 116.0)  
	
# 	assert None != calculateIntersectPoint(p1, p2, p3, p4), "line 1 line 2 should intersect"
# 	assert None != calculateIntersectPoint(p3, p4, p1, p2), "line 2 line 1 should intersect"
# 	assert None == calculateIntersectPoint(p1, p2, p5, p6), "line 1 line 3 shouldn't intersect"
# 	assert None == calculateIntersectPoint(p3, p4, p5, p6), "line 2 line 3 shouldn't intersect"
# 	assert None != calculateIntersectPoint(p1, p2, p7, p8), "line 1 line 4 should intersect"
# 	assert None != calculateIntersectPoint(p7, p8, p1, p2), "line 4 line 1 should intersect"
# 	assert None != calculateIntersectPoint(p1, p2, p9, p10), "line 1 line 5 should intersect"
# 	assert None != calculateIntersectPoint(p9, p10, p1, p2), "line 5 line 1 should intersect"
# 	assert None != calculateIntersectPoint(p7, p8, p9, p10), "line 4 line 5 should intersect"
# 	assert None != calculateIntersectPoint(p9, p10, p7, p8), "line 5 line 4 should intersect"
	
# 	print "\nSUCCESS! All asserts passed for doLinesIntersect"
コード例 #11
0
def main():
    init()
    running = True

    size = 1000, 1000

    # these are the width and height of the simulation grid
    grid_x, grid_y = int(argv[1]), int(argv[2])
    # this is how many pixels per cell in the simulation grid
    #   We need to use the grid factor because the pygame window is not
    #   the same width and height of the simulation grid size. Therefore,
    #   we scale the pygame window down to fit the simulation size
    grid_factor_x, grid_factor_y = 1000 / grid_x, 1000 / grid_y

    screen = display.set_mode(size)
    # used to track either the setting of the topleft of a rectangle,
    #   or the bottom right (if bottom right, the rectangle is completed)
    num_clicks_patch = 0
    num_clicks_patch_temp = 0
    num_clicks_exit = 0
    num_clicks_exit_temp = 0
    # the position of the mouse when the left or right mouse button is clicked
    mouse_pos_patch = ()
    mouse_pos_exit = ()
    # the position of the patch's top left corner in pixels
    patch_tl = ()
    # the position of the patch's bottom right corner in pixels
    patch_br = ()
    # the position of the exits's top left corner in pixels
    exit_tl = ()
    # the position of the exits's bottom right corner in pixels
    exit_br = ()
    patch_temp = Rect(-1, -1, 0, 0)
    exit_temp = Rect(-1, -1, 0, 0)
    # a list of patches as pygame rectangles that are being displayed
    #   on screen
    patch_list = []
    # a list of patches removed from the screen. The user can recall these
    #   with a keybind
    patch_discard_list = []
    # a list of exits as pygame rectangles that are being displayed
    #   on screen
    exit_list = []
    # a list of exits removed from the screen. The user can recall these
    #   with a keybind
    exit_discard_list = []
    # a list of 1 pixel-wide pygame rectangles that are drawn to the screen
    #   to create grid lines
    gridline_list = []

    # populate `gridline_list`
    gridline_list = populate_gridline_list(gridline_list, grid_x, grid_y,
                                           grid_factor_x, grid_factor_y)

    # main game loop will run until the user clicks the exit button in the top right corner (Windows)
    while running:
        # event loop
        for pygame_event in event.get():
            # if the user hits the window's exit button, stop the app
            if pygame_event.type == QUIT:
                running = False
            # if the user hits the mouse button in the app window
            if pygame_event.type == MOUSEBUTTONDOWN and mouse.get_focused():
                # return a list of booleans for the three major buttons on a mouse:
                #   left mouse, right mouse, and middle mouse. If an element is True,
                #   the corresponding button is pressed
                mouse_depressed = mouse.get_pressed(num_buttons=3)
                # if the user clicks ONLY the left mouse button, they are creating
                #   a patch.
                if mouse_depressed[0] and not mouse_depressed[2]:
                    # get the mouse's position with respect to the window
                    mouse_pos_patch = mouse.get_pos()
                    num_clicks_patch += 1
                    num_clicks_patch_temp = num_clicks_patch
                # if the user clicks ONLY the right mouse button, they are creating
                #   an exit.
                if mouse_depressed[2] and not mouse_depressed[0]:
                    mouse_pos_exit = mouse.get_pos()
                    num_clicks_exit += 1
                    num_clicks_exit_temp = num_clicks_exit
            if pygame_event.type == KEYDOWN and key.get_focused():
                # return a list of booleans for all the keys on the keyboard
                #   If an element is True, the corresponding key is pressed
                keys_depressed = key.get_pressed()
                # if the user presses CTRL+Z, remove the previously added patches
                #   from most recent to least recent
                if keys_depressed[K_LCTRL] and keys_depressed[
                        K_z] and not keys_depressed[K_LSHIFT]:
                    # if the user has begun to create a new patch, they can
                    #   cancel it by hitting CTRL+Z. Otherwise, CTRL+Z removes a
                    #   patch that has already been drawn
                    if patch_list and num_clicks_patch == 0:
                        patch_discard_list.append(patch_list.pop())
                        print("Number of patches:", len(patch_list))
                    else:
                        patch_tl = ()
                        num_clicks_patch = 0
                        num_clicks_patch_temp = 0
                        print("Undid patch topleft!")
                # if the user pressed CTRL+SHIFT+Z, remove the previously added exits
                #   from most recent to least recent
                elif keys_depressed[K_LSHIFT] and keys_depressed[
                        K_LCTRL] and keys_depressed[K_z]:
                    # if the user has begun to create a new exit, they can
                    #   cancel it by hitting CTRL+SHIFT+Z. Otherwise, CTRL+SHIFT+Z removes a
                    #   exit that has already been drawn
                    if exit_list and num_clicks_exit == 0:
                        exit_discard_list.append(exit_list.pop())
                        print("Number of exits:", len(exit_list))
                    else:
                        exit_tl = ()
                        num_clicks_exit = 0
                        num_clicks_exit_temp = 0
                        print("Undid exit topleft!")
                # if the user presses CTRL+Y, restore the previously removed patch
                #   from the discard patch list from most recent to least recent
                if keys_depressed[K_LCTRL] and keys_depressed[
                        K_y] and not keys_depressed[K_LSHIFT]:
                    # the user can only restore a deleted patch if they haven't
                    #   started drawing another one. Easy fix for this: press CTRL+Z
                    #   to undo the topleft of the already-begun patch, then do CTRL+Y
                    if patch_discard_list and num_clicks_patch == 0:
                        patch_list.append(patch_discard_list.pop())
                        print("Number of patches:", len(patch_list))
                # if the user pressed CTRL+SHIFT+Y, restore the previously removed exit
                #   from the discard exit list from most recent to least recent
                elif keys_depressed[K_LSHIFT] and keys_depressed[
                        K_LCTRL] and keys_depressed[K_y]:
                    # the user can only restore a deleted exit if they haven't
                    #   started drawing another one. Easy fix for this: press CTRL+SHIFT+Z
                    #   to undo the topleft of the already-begun exit, then do CTRL+SHIFT+Y
                    if exit_discard_list and num_clicks_exit == 0:
                        exit_list.append(exit_discard_list.pop())
                        print("Number of exits:", len(exit_list))

        # if the user has clicked the mouse once, store the mouse position
        #   as the top left of the rectangle to be drawn
        if num_clicks_patch_temp == 1:
            patch_tl = mouse_pos_patch
            num_clicks_patch_temp = 0
            patch_temp.topleft = patch_tl
            print("Patch topleft set at", patch_tl)
        # if the user has clicked the mouse for the second time,
        elif num_clicks_patch_temp == 2:
            patch_br = mouse_pos_patch
            patch_list.append(
                Rect(patch_tl[0], patch_tl[1], patch_br[0] - patch_tl[0],
                     patch_br[1] - patch_tl[1]))
            num_clicks_patch = 0
            num_clicks_patch_temp = 0
            print("Number of patches:", len(patch_list))

        # if the user has clicked the mouse once, store the mouse position
        #   as the top left of the rectangle to be drawn
        if num_clicks_exit_temp == 1:
            exit_tl = mouse_pos_exit
            num_clicks_exit_temp = 0
            exit_temp.topleft = exit_tl
            print("Exit topleft set at", exit_tl)
        # if the user has clicked the mouse for the second time,
        elif num_clicks_exit_temp == 2:
            exit_br = mouse_pos_exit
            exit_list.append(
                Rect(exit_tl[0], exit_tl[1], exit_br[0] - exit_tl[0],
                     exit_br[1] - exit_tl[1]))
            num_clicks_exit = 0
            num_clicks_exit_temp = 0
            print("Number of exits:", len(exit_list))

        # first blacken the screen
        screen.fill("black")
        # draw the grid lines
        for gridline in gridline_list:
            draw.rect(screen, "blue", gridline)
        # draw the patches on top of the grid lines
        for patch in patch_list:
            patch.normalize()
            draw.rect(screen, "white", patch, width=1)
        # then draw the exits over the grid lines and patches
        for exit in exit_list:
            exit.normalize()
            draw.rect(screen, "red", exit)
        # if the user has clicked to begin drawing either a patch
        #   or an exit, display the box growing and shrinking as they
        #   move their mouse so they can see what the patch/exit will look
        #   like when it's drawn
        if num_clicks_patch == 1:
            patch_temp.size = tuple(
                map(sub, mouse.get_pos(), patch_temp.topleft))
            # we'll use `patch_temp_copy` to display a proper rectangle if the user defines
            #   `patch_temp`'s topleft and then moves the mouse above or farther left than
            #   that point. Doing so creates a negative width/height in the rectangle which
            #   does not draw to the screen without glitching. Normalizing the rectangle
            #   removes the negative width/height and reassigns the topleft point in the process.
            #   Without using a copy of `patch_temp`, its top left would change every game loop,
            #   and the rectangle would not change with mouse movement correctly. If this
            #   description doesn't make sense, just trust me. If you're the kind of person
            #   who likes to define the bottom right corner first, this code lets you see
            #   that normalized (looks like a rectangle, not a cross road) rectangle change
            #   size as your mouse moves around :D
            patch_temp_copy = Rect(-1, -1, 0, 0)
            # I have to define `patch_temp_copy` like this instead of `patch_temp_copy = patch_temp`
            #   since that would just make `patch_temp_copy` an alias of `patch_temp`
            patch_temp_copy.topleft = patch_temp.topleft
            patch_temp_copy.size = patch_temp.size
            patch_temp_copy.normalize()
            draw.rect(screen, "white", patch_temp_copy, width=1)
            print(patch_temp_copy.size, "    ", end='\r')
        if num_clicks_exit == 1:
            # same theory as with `patch_temp_copy` so I'm not gonna repeat it...
            exit_temp.size = tuple(map(sub, mouse.get_pos(),
                                       exit_temp.topleft))
            exit_temp_copy = Rect(-1, -1, 0, 0)
            exit_temp_copy.topleft = exit_temp.topleft
            exit_temp_copy.size = exit_temp.size
            exit_temp_copy.normalize()
            draw.rect(screen, "red", exit_temp_copy)
            print(exit_temp_copy.size, "    ", end='\r')

        # this updates the contents of the surface
        display.flip()

        # if the user has clicked the exit button, ask them if they either want to create
        #   the terrain or completely exit the editor. Give them a second chance if they
        #   want to quit. That way they don't accidentally lose their progress.
        if not running:
            response = input(
                "Would you like to create the terrain with this model? (y/n) ")
            if response == 'y':
                # create the terrain grid from the rectangles drawn in the pygame window
                terrain_grid = create_terrain_grid(patch_list, exit_list,
                                                   grid_x, grid_y,
                                                   grid_factor_x,
                                                   grid_factor_y)
                # draw converted rectangles to the .txt file
                output_to_file(grid_x, grid_y, terrain_grid)
                # save the pygame screen as a .png to use as the background image of the simulation
                #   visualization .gif
                save_screen_as_bkgr(screen)
                # update the patches document in the `params.json` file
                update_patches(patch_list, grid_factor_x, grid_factor_y)
            elif response == 'n':
                second_response = input("Are you sure? (Y/N) ")
                if second_response == "Y":
                    print("Quitting terrain editor.")
                elif second_response == "N":
                    running = True
                    print("Continuing terrain editor.")
                else:
                    running = True
                    print(
                        "Invalid response ('Y' or 'N' only, please). Continuing terrain editor."
                    )
            else:
                running = True
                print(
                    "Invalid response ('y' or 'n' only, please). Continuing terrain editor."
                )
    quit()
コード例 #12
0
ファイル: geometry.py プロジェクト: jarriett/will-it-fit
# If the point where two lines intersect is inside both line's bounding
# rectangles then the lines intersect. Returns intersect point if the line
# intesect o None if not
def calculateIntersectPoint(points):
    p1 = points[0][0]
    p2 = points[0][1]
    p3 = points[1][0]
    p4 = points[1][1]
  
   p = getIntersectPoint(p1, p2, p3, p4)
  
   if p is not None:               
       width = p2[0] - p1[0]
       height = p2[1] - p1[1]       
       r1 = Rect(p1, (width , height))
       r1.normalize()
      
       width = p4[0] - p3[0]
       height = p4[1] - p3[1]
       r2 = Rect(p3, (width, height))
       r2.normalize()              

       # Ensure both rects have a width and height of at least 'tolerance' else the
       # collidepoint check of the Rect class will fail as it doesn't include the bottom
       # and right hand side 'pixels' of the rectangle
       tolerance = 1
       if r1.width < tolerance:
            r1.width = tolerance
                    
       if r1.height < tolerance:
            r1.height = tolerance
コード例 #13
-1
def calculateIntersectPoint(p1, p2, p3, p4):

    p = getIntersectPoint(p1, p2, p3, p4)

    if p is not None:
        width = p2[0] - p1[0]
        height = p2[1] - p1[1]
        r1 = Rect(p1, (width, height))
        r1.normalize()

        width = p4[0] - p3[0]
        height = p4[1] - p3[1]
        r2 = Rect(p3, (width, height))
        r2.normalize()

        # Ensure both rects have a width and height of at least 'tolerance' else the
        # collidepoint check of the Rect class will fail as it doesn't include the bottom
        # and right hand side 'pixels' of the rectangle
        tolerance = 1
        if r1.width < tolerance:
            r1.width = tolerance

        if r1.height < tolerance:
            r1.height = tolerance

        if r2.width < tolerance:
            r2.width = tolerance

        if r2.height < tolerance:
            r2.height = tolerance

        for point in p:
            try:
                res1 = r1.collidepoint(point)
                res2 = r2.collidepoint(point)
                if res1 and res2:
                    point = [int(pp) for pp in point]
                    return point
            except:
                # sometimes the value in a point are too large for PyGame's Rect class
                str = "point was invalid  ", point
                print(str)

        # This is the case where the infinately long lines crossed but
        # the line segments didn't
        return None

    else:
        return None