Python _源_rgb(1,0,0) cr.set\u line\u join(cairo.line\u join\u ROUND) cr.中风() 等级人行道(gtk.图纸区域): 定义初始化(自): gtk.图纸区域(自) self.connect(“expose_事件”,self.expose) def暴露(自我、小部件、事件): cr=widget.window.cairo\u create() rect=self.get\u分配() w=矩形宽度 h=垂直高度 cr.save() cr.translate(w/2,h/2) 比例=20 cr刻度(刻度,-刻度) cr.translate(40,92) twocurves=stepcurve.extend(stepcurve) cstart=305 cr.set_源_rgb(0,0.5,0) 对于阶跃曲线中的p[cstart:cstart+121]: cr.arc(p.x,p.y,0.1,0,2*pi) cr.fill() cr.move_to(阶跃曲线[cstart].x,阶跃曲线[cstart].y) 对于阶跃曲线[cstart+1:cstart+121]中的p: cr.line_至(p.x,p.y) cr.set\u line\u join(cairo.line\u join\u ROUND) cr.restore() cr.set_源_rgb(1,0,0) cr.set\U线条\U宽度(1) cr.中风() cr.save() cr.translate(w/2,h/2) 比例=20 cr刻度(刻度,-刻度) cr.translate(40,92) cr.move_至(阶跃曲线[cstart+120].x,阶跃曲线[cstart+120].y) 对于阶跃曲线[cstart+120+1:cstart+360+1]中的p: cr.line_至(p.x,p.y) cr.restore() cr.set_源_rgb(0,0,1) cr.set\U线条\U宽度(1) cr.中风() canvas=canvas() 画布。设置大小请求(140150) toppanel.pack_开始(画布、假、假) toppanel.pack_start(gtk.vsepator(),False,False) 人行道 人行道。设置大小请求(1000,-1) toppanel.pack_start(人行道,正确,正确) def更换角度(par): mec.组装(第get_值()部分-60) canvas.queue_draw() 角度调整=gtk.调整(值=0,下=0,上=360,步长=1) 角度刻度=gtk.hs刻度(调整=角度调整) 角度刻度设置值位置(gtk位置左) angleScale.connect(“值已更改”,更改角度) 面板。打包开始(角度刻度、假、假) 窗口设置位置(gtk.WIN位置中心) window.show_all() gtk.main()

Python _源_rgb(1,0,0) cr.set\u line\u join(cairo.line\u join\u ROUND) cr.中风() 等级人行道(gtk.图纸区域): 定义初始化(自): gtk.图纸区域(自) self.connect(“expose_事件”,self.expose) def暴露(自我、小部件、事件): cr=widget.window.cairo\u create() rect=self.get\u分配() w=矩形宽度 h=垂直高度 cr.save() cr.translate(w/2,h/2) 比例=20 cr刻度(刻度,-刻度) cr.translate(40,92) twocurves=stepcurve.extend(stepcurve) cstart=305 cr.set_源_rgb(0,0.5,0) 对于阶跃曲线中的p[cstart:cstart+121]: cr.arc(p.x,p.y,0.1,0,2*pi) cr.fill() cr.move_to(阶跃曲线[cstart].x,阶跃曲线[cstart].y) 对于阶跃曲线[cstart+1:cstart+121]中的p: cr.line_至(p.x,p.y) cr.set\u line\u join(cairo.line\u join\u ROUND) cr.restore() cr.set_源_rgb(1,0,0) cr.set\U线条\U宽度(1) cr.中风() cr.save() cr.translate(w/2,h/2) 比例=20 cr刻度(刻度,-刻度) cr.translate(40,92) cr.move_至(阶跃曲线[cstart+120].x,阶跃曲线[cstart+120].y) 对于阶跃曲线[cstart+120+1:cstart+360+1]中的p: cr.line_至(p.x,p.y) cr.restore() cr.set_源_rgb(0,0,1) cr.set\U线条\U宽度(1) cr.中风() canvas=canvas() 画布。设置大小请求(140150) toppanel.pack_开始(画布、假、假) toppanel.pack_start(gtk.vsepator(),False,False) 人行道 人行道。设置大小请求(1000,-1) toppanel.pack_start(人行道,正确,正确) def更换角度(par): mec.组装(第get_值()部分-60) canvas.queue_draw() 角度调整=gtk.调整(值=0,下=0,上=360,步长=1) 角度刻度=gtk.hs刻度(调整=角度调整) 角度刻度设置值位置(gtk位置左) angleScale.connect(“值已更改”,更改角度) 面板。打包开始(角度刻度、假、假) 窗口设置位置(gtk.WIN位置中心) window.show_all() gtk.main(),python,math,geometry,genetic-algorithm,evolutionary-algorithm,Python,Math,Geometry,Genetic Algorithm,Evolutionary Algorithm,这是一个有趣的问题,尽管我认为它超出了堆栈溢出的范围:这不是几分钟内就能解决的问题,所以我将在这里留下一个提纲,如果有任何进展,我会更新它。任何方法都有三个部分: 记录足迹:连杆是否断裂?脚印的形状正确吗?它有多平?这个动议有多顺利?它在平坦的部分花费足够的时间吗 搜索幻数的好值。尚不清楚这是否一定是一种进化算法(尽管我可以理解为什么这样一种算法的想法会吸引西奥·詹森,因为它与他艺术中的动物隐喻相吻合);或许其他方法,如局部搜索(爬山)或模拟退火,也会有成效 寻找良好的武器配置。这就是进化方法似

这是一个有趣的问题,尽管我认为它超出了堆栈溢出的范围:这不是几分钟内就能解决的问题,所以我将在这里留下一个提纲,如果有任何进展,我会更新它。任何方法都有三个部分:

  • 记录足迹:连杆是否断裂?脚印的形状正确吗?它有多平?这个动议有多顺利?它在平坦的部分花费足够的时间吗

  • 搜索幻数的好值。尚不清楚这是否一定是一种进化算法(尽管我可以理解为什么这样一种算法的想法会吸引西奥·詹森,因为它与他艺术中的动物隐喻相吻合);或许其他方法,如局部搜索(爬山)或模拟退火,也会有成效

  • 寻找良好的武器配置。这就是进化方法似乎最有价值的地方

  • 您可以在我的Javascript/canvas演示中尝试不同的魔术数字,看看您可以得到什么样的运动(例如,CD=55.4非常有趣)。顺便说一句,有一个整体将连杆的构型空间连接到拓扑流形


    我在演示中添加了一些简单的评分。地面分数是脚在地面上的循环分数,我认为是y坐标在最低点公差范围内的所有点。当脚在地面上时,阻力分数是任意两个水平速度之间的最大差值。(它总是负值,因此值越高=速度差异越小=越好。)

    但困难就在这里。为了编程任何类型的搜索,我需要能够组合这些分数。但我如何平衡它们之间的关系呢?詹森魔法数字给我的得分是:0.520;拖缆芯:-0.285。如果我设置AC=10,GH=65,EH=50,我得到groundScore:0.688;拖缆芯:-0.661。几乎70%的时间脚都在地上。但是起飞很慢。这比詹森的好还是坏


    我认为获得实际的工程反馈以确定一个好的分数将是这里的大问题,而不是实际的搜索。

    这是一个很好的问题,但需要很多思考!同时,我还冒昧地将您的代码翻译成Javascript,以便其他堆栈溢出的贡献者可以使用这个奇妙的机制进行实验:做得好,@Gareth Rees!我将很快更新我的问题,以便包括我对这个问题的一些想法。只有一个观察结果:我认为E点和F点在javascript模型上交换了。此外,工作机构由每个“动物肢体”三个机构组成,它们之间有120度的相位差(三个同时出现的肢体的动画非常令人毛骨悚然!)。非常感谢你的贡献!!我的模型上的标签与代码中的标签相同(我相当机械地对其进行了转换)。所需机械装置的数量是腿在地面上停留时间的函数。例如,小程序有一半的时间在地面上,因此每个肢体只需要两个机构。小程序的参数化版本非常棒!当我得到一些拟合错误的图形时,我会更新我的代码!你在介绍分数方面做得很好,加雷斯!作为一个建议,我将尝试测试水平位移而不是速度,因为结果将与用于构建连杆的长度单位相同。此外,我们必须注意,某些组合会改变接地接触路径的坡度,因此与此路径相关的点应在距离双切线(如果路径具有一些凹截面)或最小曲率切线(如果路径完全凸)线的公差距离内。事实上,这是一个非常棘手的问题……我决定(至少现在)我会
    # coding: utf-8
    
    import pygtk
    pygtk.require('2.0')
    import gtk, cairo
    from math import *
    
    class Mechanism():
        def __init__(s):
            pass
    
        def assemble(s, angle):
    
            # magic numbers (unmutated)
            mu = [38, 7.8, 15, 50, 41.5, 39.3, 61.9, 55.8, 40.1, 39.4, 36.7, 65.7, 49]
    
            # mutations
            mut = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    
            # mutated
            mn = [mu[n]+mut[n] for n in range(13)]
    
            s.A = Point(0,0)
            s.B = Point(-mn[0], -mn[1])
    
            s.C = fromPoint(s.A, mn[2], angle)
            s.ac = Line(s.A, s.C)
    
            s.D = linkage(s.C, mn[3], s.B, mn[4])
            s.cd = Line(s.C, s.D)
            s.bd = Line(s.B, s.D)
    
            s.E = linkage(s.B, mn[5], s.C, mn[6])
            s.be = Line(s.B, s.E)
            s.ce = Line(s.C, s.E)
    
            s.F = linkage(s.D, mn[7], s.B, mn[8])
            s.df = Line(s.D, s.F)
            s.bf = Line(s.B, s.F)
    
            s.G = linkage(s.F, mn[9], s.E, mn[10])
            s.fg = Line(s.F, s.G)
            s.eg = Line(s.E, s.G)
    
            s.H = linkage(s.G, mn[11], s.E, mn[12])
            s.gh = Line(s.G, s.H)
            s.EH = Line(s.E, s.H)
    
    
            return s.H
    
    
    class Point:
        def __init__(self, x, y):
            self.x, self.y = float(x), float(y)
        def __str__(self):
            return "(%.2f, %.2f)" % (self.x, self.y)
    
    class Line:
        def __init__(self, p1, p2):
            self.p1, self.p2 = p1, p2
        def length(self):
            return sqrt((p1.x-p2.x)**2 + (p1.y-p2.y)**2)
    
    def fromPoint(point, distance, angle):
        angle = radians(angle)
        return Point(point.x + distance * cos(angle),
            point.y + distance * sin(angle))
    
    def distance(p1, p2):
        return sqrt( (p1.x - p2.x)**2 + (p1.y - p2.y)**2 )
    
    def ccw(p1, p2, px):
        """ Test if px is at the right side of the line p1p2 """
        ax, ay, bx, by = p1.x, p1.y, p2.x, p2.y
        cx, cy = px.x, px.y
        return (bx-ax)*(cy-ay)-(by-ay)*(cx-ax) < 0
    
    def linkage(p1, l1, p2, l2):
        l1 = float(l1)
        l2 = float(l2)
        dx,dy = p2.x-p1.x, p2.y-p1.y
        d = sqrt(dx**2 + dy**2)                             # distance between the centers
        a = (l1**2 - l2**2 + d**2) / (2*d)                  # distance from first center to the radical line
        M = Point(p1.x + (dx * a/d), p1.y + (dy * a/d))     # intersection of centerline with radical line
        h = sqrt(l1**2 - a**2)                              # distance from the midline to any of the points
        rx,ry = -dy*(h/d), dx*(h/d)
        # There are two results, but only one (the correct side of the line) must be chosen
        R1 = Point(M.x + rx, M.y + ry)
        R2 = Point(M.x - rx, M.y - ry)
        test1 = ccw(p1, p2, R1)
        test2 = ccw(p1, p2, R2)
        if test1:
            return R1
        else:
            return R2
    
    
    
    
    ###############################33
    
    mec = Mechanism()
    stepcurve = [mec.assemble(p) for p in xrange(360)]
    
    window=gtk.Window()
    panel = gtk.VBox()
    window.add(panel)
    toppanel = gtk.HBox()
    panel.pack_start(toppanel)
    
    class Canvas(gtk.DrawingArea):
        def __init__(self):
            gtk.DrawingArea.__init__(self)
            self.connect("expose_event", self.expose)
    
        def expose(self, widget, event):
            cr = widget.window.cairo_create()
            rect = self.get_allocation()
            w = rect.width
            h = rect.height
            cr.translate(w*0.85, h*0.3)
            scale = 1
            cr.scale(scale, -scale)
            cr.set_line_width(1)
    
            def paintpoint(p):
                cr.arc(p.x, p.y, 1.2, 0, 2*pi)
                cr.set_source_rgb(1,1,1)
                cr.fill_preserve()
                cr.set_source_rgb(0,0,0)
                cr.stroke()
    
            def paintline(l):
                cr.move_to(l.p1.x, l.p1.y)
                cr.line_to(l.p2.x, l.p2.y)
                cr.stroke()
    
            for i in mec.__dict__:
                if mec.__dict__[i].__class__.__name__ == 'Line':
                    paintline(mec.__dict__[i])
    
            for i in mec.__dict__:
                if mec.__dict__[i].__class__.__name__ == 'Point':
                    paintpoint(mec.__dict__[i])
    
            cr.move_to(stepcurve[0].x, stepcurve[0].y)
            for p in stepcurve[1:]:
                cr.line_to(p.x, p.y)
            cr.close_path()
            cr.set_source_rgb(1,0,0)
            cr.set_line_join(cairo.LINE_JOIN_ROUND)
            cr.stroke()
    
    class FootPath(gtk.DrawingArea):
        def __init__(self):
            gtk.DrawingArea.__init__(self)
            self.connect("expose_event", self.expose)
    
        def expose(self, widget, event):
            cr = widget.window.cairo_create()
            rect = self.get_allocation()
            w = rect.width
            h = rect.height
    
            cr.save()
            cr.translate(w/2, h/2)
    
            scale = 20
            cr.scale(scale, -scale)
    
            cr.translate(40,92)
    
            twocurves = stepcurve.extend(stepcurve)
    
            cstart = 305
            cr.set_source_rgb(0,0.5,0)
            for p in stepcurve[cstart:cstart+121]:
                cr.arc(p.x, p.y, 0.1, 0, 2*pi)
                cr.fill()
    
            cr.move_to(stepcurve[cstart].x, stepcurve[cstart].y)
            for p in stepcurve[cstart+1:cstart+121]:
                cr.line_to(p.x, p.y)
            cr.set_line_join(cairo.LINE_JOIN_ROUND)
            cr.restore()
            cr.set_source_rgb(1,0,0)
            cr.set_line_width(1)
            cr.stroke()
    
    
    
    
            cr.save()
            cr.translate(w/2, h/2)
            scale = 20
            cr.scale(scale, -scale)
            cr.translate(40,92)
    
            cr.move_to(stepcurve[cstart+120].x, stepcurve[cstart+120].y)
            for p in stepcurve[cstart+120+1:cstart+360+1]:
                cr.line_to(p.x, p.y)
            cr.restore()
            cr.set_source_rgb(0,0,1)
            cr.set_line_width(1)
            cr.stroke()
    
    
    
    canvas = Canvas()
    canvas.set_size_request(140,150)
    toppanel.pack_start(canvas, False, False)
    
    toppanel.pack_start(gtk.VSeparator(), False, False)
    
    footpath = FootPath()
    footpath.set_size_request(1000,-1)
    toppanel.pack_start(footpath, True, True)
    
    
    def changeangle(par):
        mec.assemble(par.get_value()-60)
        canvas.queue_draw()
    angleadjust = gtk.Adjustment(value=0, lower=0, upper=360, step_incr=1)
    angleScale = gtk.HScale(adjustment=angleadjust)
    angleScale.set_value_pos(gtk.POS_LEFT)
    angleScale.connect("value-changed", changeangle)
    panel.pack_start(angleScale, False, False)
    
    
    window.set_position(gtk.WIN_POS_CENTER)
    window.show_all()
    gtk.main()