连点成图:享受创建图形的乐趣

1.  使用 wxpython 做基本的 GUI ;

2.  使用 Python 实现策略模式;

3.  点阵图的算法,使用程序生成, 既有趣也很锻炼算法思维连带激发创造力哦。

改进点: 生成更复杂更美妙的图案; 拖拽功能创作和保存; 关卡设置。你也来试试吧! 如果有兴趣做成移动游戏, 那就更棒了!

源程序:

  linkpointsUI.py

# -*- coding: utf8 -*-
# -------------------------------------------------------------------------------
# Name:        linkpointsUI.py
# Purpose:     a game which join points to a gragh and enjoy
#
# Author:      qin.shuq
#
# Created:      11/29/2014
# Copyright:   (c) qin.shuq 2014
# Licence:     ONLY BE USED FOR STUDY
#-------------------------------------------------------------------------------

import wx
import time
from LinkPointStrategy import *

class LinkPointsFrame(wx.Frame):
    ‘‘‘
       generate dotSize * dotSize dotted graph and app ui
    ‘‘‘
    def __init__(self, parent, title, dotSize=18, uiSize=(840,560)):
        wx.Frame.__init__(self, parent, title=title, size=uiSize)
        self.mainPanel = None
        self.dc = None
        self.dotSize = dotSize
        self.displayDemoTimer = None

        bottomSpace = 50
        uiWidth = uiSize[0]
        panelHeight = uiSize[1] - bottomSpace

        self.origin = 10
        self.pointRadius = 2
        self.intervalBetweenPoints = (panelHeight-self.origin*2) / (self.dotSize-1)

        self.mainPanelSize = (panelHeight, panelHeight)
        self.ctrlPanelSize = (uiWidth - self.mainPanelSize[0], panelHeight)

        self.initUI()

    def initUI(self):

        ### UI Design follows top-down thinking and down-top building

        bigPanel = wx.Panel(self, name="WhileWindow")
        font = wx.Font(12, wx.ROMAN, wx.NORMAL, wx.NORMAL)

        hboxLayout = wx.BoxSizer(wx.HORIZONTAL)
        self.mainpanel = wx.Panel(bigPanel, name="mainPanel", size=self.mainPanelSize)
        self.mainpanel.SetBackgroundColour(‘#fffff0‘)

        ctrlPanel = wx.Panel(bigPanel, name="ctrlPanel", size=self.ctrlPanelSize)

        hboxLayout.Add(self.mainpanel, 0, wx.EXPAND|wx.ALL, 10)
        hboxLayout.Add(ctrlPanel, 0, wx.EXPAND|wx.ALL, 10)
        bigPanel.SetSizer(hboxLayout)

        topPanel = wx.Panel(ctrlPanel, name="topPanel")
        staticText = wx.StaticText(topPanel, label=decodeUTF8("How to Play: \n\nJust link points to build a graph, \nSo Easy And Enjoy Yourself !"))
        staticText.SetFont(font)

        btnBoxSizer = wx.BoxSizer(wx.VERTICAL)

        createNewBtn = wx.Button(ctrlPanel, name="CreateNew", label=decodeUTF8("创作"))
        saveBtn = wx.Button(ctrlPanel, name="SaveWork", label=decodeUTF8("保存"))
        seeDemoBtn = wx.Button(ctrlPanel, name="seeDemo", label=decodeUTF8("欣赏"))

        self.Bind(wx.EVT_BUTTON, self.createNewDottedGraph, createNewBtn)
        self.Bind(wx.EVT_BUTTON, self.createDemoGraph, seeDemoBtn)

        btnBoxSizer.Add(createNewBtn)
        btnBoxSizer.Add(saveBtn)
        btnBoxSizer.Add(seeDemoBtn)

        vboxLayout = wx.BoxSizer(wx.VERTICAL)
        vboxLayout.Add(topPanel, 1, wx.EXPAND|wx.ALL, 5)
        vboxLayout.Add(btnBoxSizer, 1, wx.EXPAND|wx.ALL, 5)
        ctrlPanel.SetSizer(vboxLayout)

        self.Show(True)

        # show demo
        self.createDemoGraph()

    def createNewDottedGraph(self, event=None):
        if self.displayDemoTimer:
            self.displayDemoTimer.Stop()
        if self.dc:
            self.dc.Clear()
        self.dc = wx.ClientDC(self.mainpanel)
        self.dc.SetPen(wx.Pen(‘GREEN‘))
        self.dc.SetBrush(wx.Brush(‘GREEN‘))
        for xcoord in range(self.origin, self.mainPanelSize[0] + self.intervalBetweenPoints, self.intervalBetweenPoints):
            for ycoord in range(self.origin, self.mainPanelSize[1] + self.intervalBetweenPoints, self.intervalBetweenPoints):
                self.dc.DrawPoint(xcoord, ycoord)
                self.dc.DrawCircle(xcoord,ycoord, self.pointRadius)

    def drawGraph(self, allLines):
        ‘‘‘
           a line is a tuple of ((x1,y1), (x2, y2))
        ‘‘‘
        #print ‘***************************************‘
        for line in allLines:
            #print line[0][0], ‘ ‘, line[0][1], ‘ ‘, line[1][0], ‘ ‘, line[1][1]
            x1 = self.obtainRealCoords(line[0][0])
            y1 = self.obtainRealCoords(line[0][1])
            x2 = self.obtainRealCoords(line[1][0])
            y2 = self.obtainRealCoords(line[1][1])
            self.dc.DrawLine(x1, y1, x2, y2)

    def createDemoGraph(self, event=None):
        self.createNewDottedGraph()
        linkpointsStrategy = LinkPointStrategy(self.dotSize)
        allLines = linkpointsStrategy.obtainAllLinesByLinkPoints()
        self.drawGraph(allLines)

        try:
            anoStrategy = LinkPointStrategy.getStrategy("anoStrategy")
        except Exception, args:
            print args

        def myStrategy(allPoints, size):
            return [(point, (point[0]+1, point[1]+1)) for point in allPoints if (point[0] == point[1] and point[0]<size-1)]

        LinkPointStrategy.registerStrategy("my", myStrategy)
        LinkPointStrategy.setStrategy("my")
        self.createNewDottedGraph()
        self.drawGraph(linkpointsStrategy.obtainAllLinesByLinkPoints())

        def displayDemo(*args, **kwargs):
            allStrategies = linkpointsStrategy.getAllStrategies()
            for strategyName in allStrategies.keys():
                self.createNewDottedGraph()
                linkpointsStrategy.setStrategy(strategyName)
                self.drawGraph(linkpointsStrategy.obtainAllLinesByLinkPoints())
                time.sleep(2)

        self.displayDemoTimer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, displayDemo, self.displayDemoTimer)
        self.displayDemoTimer.Start(3000, oneShot=False)

    def obtainRealCoords(self, localCoord):
        ‘‘‘
            将逻辑坐标 (x,y) 转换为 实际坐标 (real_x, real_y).
            eg. 假设原点坐标是 (15,15), 点间隔为 (30, 30), 则 (1,1) -> (45,45)
            这样在绘图时就可以专注于以逻辑坐标来思考,摒弃实际坐标的细节干扰
        ‘‘‘
        return self.origin+localCoord*self.intervalBetweenPoints

# utils
def decodeUTF8(msg):
    return msg.decode(‘utf8‘)

def main():

    app = wx.App(False)
    frame = LinkPointsFrame(None, decodeUTF8(‘连点成图: 享受创建图形的乐趣‘))
    app.MainLoop()

if __name__ == ‘__main__‘:
    main()

LinkPointStrategy.py

# -*- coding: utf8 -*-
# -------------------------------------------------------------------------------
# Name:        LinkPointStrategy.py
# Purpose:     varieties of algorithms for linking points
#
# Author:      qin.shuq
#
# Created:     11/29/2014
# Copyright:   (c) qin.shuq 2014
# Licence:     ONLY BE USED FOR STUDY
# -------------------------------------------------------------------------------

def simpleLoopStrategyOfLinkpoints(allPoints, size):
    pairs = []
    for i in range(size):
        if i*2 <= size-1:
            pairs.append((i, size-1-i))
    allLines = []
    for pair in pairs:
        allLines.append( ((pair[0], pair[0]), (pair[0], pair[1])) )
        allLines.append( ((pair[0], pair[0]), (pair[1], pair[0])) )
        allLines.append( ((pair[0], pair[1]), (pair[1], pair[1])) )
        allLines.append( ((pair[1], pair[0]), (pair[1], pair[1])) )
    return allLines

def loopStrategyOfLinkpoints(allPoints, size):
    pairs = []
    for i in range(size):
        if i*2 <= size-1:
            pairs.append((i, size-1-i))
    allLines = []
    for pair in pairs:
        begin = (pair[0], pair[0])
        end = (pair[1], pair[1])
        for localXCoord in range(pair[0], pair[1], 1):
            allLines.append(((pair[0], localXCoord), (pair[0], localXCoord+1)))
            allLines.append(((pair[1], localXCoord), (pair[1], localXCoord+1)))
        for localYCoord in range(pair[0], pair[1], 1):
            allLines.append(((localYCoord, pair[0]), (localYCoord+1, pair[0])))
            allLines.append(((localYCoord, pair[1]), (localYCoord+1, pair[1])))
    return allLines

def defaultStrategyOfLinkpoints(allPoints, size):
    return [( point, (point[0]+1, point[1]+1) )
                for point in allPoints if not isRightOrButtomBoundPoint(point, size)]

def isRightOrButtomBoundPoint(point, size):
    localXCoord = point[0]
    localYCoord = point[1]
    return localXCoord == size-1 or localYCoord == size-1

class StrategyManager(object):

    def __init__(self):
        self.strategiesForlinkPoints = {
            ‘default‘: defaultStrategyOfLinkpoints,
            ‘loop‘: loopStrategyOfLinkpoints,
            ‘simpleLoop‘: simpleLoopStrategyOfLinkpoints
        }
        self.DEFAULT_STRATEGY = self.strategiesForlinkPoints[‘default‘]
        self.CURR_STRATEGY = self.DEFAULT_STRATEGY

    def getStrategy(self, strategyName):
        strategyForLinkPoints = self.strategiesForlinkPoints.get(strategyName)
        if strategyForLinkPoints is None:
            raise Exception(‘No stragegy named "%s". You can write one. ‘ % strategyName)
        return strategyForLinkPoints

    def registerStrategy(self, strategyName, strategyForLinkPoints):
        oldStrategy = self.strategiesForlinkPoints.get(strategyName)
        if oldStrategy:
            self.strategiesForlinkPoints[‘old_‘ + strategyName] = oldStrategy
        self.strategiesForlinkPoints[strategyName] = strategyForLinkPoints

    def setCurrStrategy(self, strategyName):
        self.CURR_STRATEGY = self.getStrategy(strategyName)

    def getCurrStratety(self):
        return self.CURR_STRATEGY

    def getAllStrategies(self):
        return self.strategiesForlinkPoints

class LinkPointStrategy(object):
    ‘‘‘
       just think in a dotted graph of  (0,0) - (dotSize-1, dotSize-1) with interval of points = 1
       (0,0), (0,1), ... , (0, dotSize-1)
       (1,0), (1,1), ... , (1, dotSize-1)
        ... ,  ... , ... ,  ...
       (dotSize-1,0), (dotSize-1, 1), ..., (dotSize-1, dotSize-1)
       and output a set of [((x1,y1), (x2,y2)), ..., ((xm,ym), (xn,yn))]
    ‘‘‘

    strategyManager = StrategyManager()

    def __init__(self, dotSize):
        self.dotSize = dotSize
        self.allPoints = []

        for localXCoord in range(dotSize):
            for localYCoord in range(dotSize):
                self.allPoints.append((localXCoord, localYCoord))

    @classmethod
    def setStrategy(cls, strategyName):
        cls.strategyManager.setCurrStrategy(strategyName)

    @classmethod
    def getStrategy(cls, strategyName):
        return cls.strategyManager.getStrategy(strategyName)

    @classmethod
    def registerStrategy(cls, strategyName, strategyFunc):
        cls.strategyManager.registerStrategy(strategyName, strategyFunc)

    @classmethod
    def getAllStrategies(cls):
        return cls.strategyManager.getAllStrategies()

    def obtainAllLinesByLinkPoints(self):
        ‘‘‘
           generate all lines between points according to given strategy which is a algorithm of linking points
           line: a tuple of (x1, y1, x2, y2)
           note: (x1, y1, x2, y2) are local coordinates which will be converted into real coordinates upon drawing
        ‘‘‘
        currStrategy = LinkPointStrategy.strategyManager.getCurrStratety()
        return currStrategy(self.allPoints, self.dotSize)
时间: 2024-10-06 09:36:26

连点成图:享受创建图形的乐趣的相关文章

利用请求的JSON数据创建图形图层

先看效果图: 包含三个部分:信息窗口(标题是要素的某个属性信息,其余是感兴趣的属性信息).图上图形按照某一属性大小不一显示,图例 1.创建底图用于存放以上三部分: "esri/Map","esri/views/MapView" var map = new Map({ basemap:"dark-gray"}); var view = new MapView({ map:map, container:"viewDiv", cen

HTML5 Canvas ( 创建图形对象 ) createImageData

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>canvas</title> <script type="text/javascript" src="../js/jQuery.js"></script> <style type="text/css">

图的创建和遍历(BFS/DFS)

图的表示方法主要有邻接矩阵和邻接表.其中邻接表最为常用,因此这里便以邻接表为例介绍一下图的创建及遍历方法. 创建图用到的结构有两种:顶点及弧 struct ArcNode { int vertexIndex; //该弧指向的顶点位置 struct ArcNode* next; //指向下一个弧 InfoType info; //该弧的相关信息,如权重等 }; struct Vertex { VertexType data; //顶点信息 ArcNode* firstArc; //指向第一条依附该

Surfer8.0 汉化注册版 1CD(地质工作者必备的专业成图软件)中文版

ABZ.Design.Flow.Solutions.DesigNet.v4.16 1CD Aspen Economic Evaluation Family v7.3.2-ISO 1DVD Avenza Geographic Imager 4.0 for Phtotoshop CS6 1CD Avenza Mapublisher v9.0 for Phtotoshop CS6 Win64 1CD Bentley Map Enterprise SS3 V8i 08.11.09.91 1CD Data

IOS-绘制饼图等多种图形

参考网址:http://www.cnblogs.com/zhw511006/archive/2011/10/19/2218194.html http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/ IOS-绘制饼图等多种图形,码迷,mamicode.com

Cacti 之 断续成图 和 Result from SNMP not valid

问题一.断续成图 刚开始做了习惯性尝试: 网页端删除元数据和视图并在命令行删除对应源数据,没有效果,查了国内外论坛的网站,没啥效果,有一位国内博友也是删除原有再新建,万般无奈把整个设备删除,并删除所有相关源数据(命令行),重建第二天正常了... 这样毕竟心里不踏实啊所以查看了下日志,看见了下面一条: Poller[0] Maximum runtime of 298 seconds exceeded. Exiting. 查了下是因为监测点设置过多导致cacti通过snmpget取完所有数据的时间超

航摄比例尺与成图比例尺

航摄比例尺与成图比例尺的关系 所谓航摄比例尺:是指空中摄影计划设计时的相片比例尺,是由焦距f/航高来确定的. 成图比例尺 航摄比例尺 影像地面分辨率(m) 1:5000 1:10 000~1:20 000 0.4~0.8 1:10 000 1:20 000~1:40 000 0.8~1.6 1:25 000 1:25 000~1:60 000 1.0~2.4 1:50 000 1:35 000~1:80 000 1.4~3.2 基于胶片相机航空摄影时, DOM比例尺与摄影比例尺的对应关系见表:

如何图形化创建oracle数据库

需要注意的几点 1.如果用oracle客户端访问服务器的话必须把服务器的主机名写成(计算机的名称)Oracle创建数据库的方法 2.navigate如何远程oracle数据库 E:\app\lenovo\product\11.1.0\client_1\BIN下面的oci.dll的文件替换掉naviaget相应的文件 创建数据库的方法有 1.通过运行Oracle Database Configuration Assistant 创建配置或删除数据库(也可在命令行下输入dbca):2.用命令行的方式

蓝桥杯 - 打印十字图 (文字图形类)

打印十字图 时间限制:1.0s   内存限制:256.0MB 问题描述 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示: ..$$$$$$$$$$$$$.. ..$...........$.. $$$.$$$$$$$$$.$$$ $...$.......$...$ $.$$$.$$$$$.$$$.$ $.$...$...$...$.$ $.$.$$$.$.$$$.$.$ $.$.$...$...$.$.$ $.$.$.$$$$$.$.$.$ $.$.$...$...$.$.$ $