用Racket语言写了一个万花筒的程序
用Racket语言写了一个万花筒的程序
来源:https://blog.csdn.net/chinazhangyong/article/details/79362394
https://github.com/OnRoadZy
https://blog.csdn.net/chinazhangyong
Racket语言是Lisp语言的一个方言。Lisp语言具有神奇的魔力,可以全方位诠释哲学,而不像其它语言主要能够表达数学。
这是我用它写的第一个完整程序,在此纪念一下下。
先来看看我的万花筒的神奇魅力,我相信以下画出来的图(带参数,可按参数重新绘出来)任何一个外边买的万花板都画不出来。不信来比:
- 这一个,注意全是尖角,中间空心呈方形:
- 这一个,花瓣中间的脉络全是直线,花心有两个圆:
- 能画出三角形吗?而且中间镶钻,两颗!
- 这个我画出来自己都被震撼了,如此的完美!
这个是不是超有立体感,不知进入了哪一个维度:
这一个,能不能找到冬天围脖的的温暖?不过哪个建筑这样修一定会拿大奖。
这个,怎么画出来的?(揭秘:将轨道起始角自图中值依次增加5并点画图按钮执行画图,经过N次之后,就出现这个神奇效果啦!)
这个,看起来很常规,不过,仔细看看!(揭秘:这是多次调整转轮半径后得到的效果。不过具体怎么的记不得了,可以自己去试。)
最后贴上源程序:
;=============================================================
;artascope.rkt
;主程序:
#lang racket
(require racket/gui)
(require racket/draw)
(require "model-simple.rkt")
(include "view-main.rkt")
(send main-frame show #t)
;=======================================================
;model-simple.rkt
;万花筒模型
(module model-simple racket
(provide draw-artascope
set-f-center
get-af0 set-af0 get-ap0 set-ap0
get-rf set-rf get-rw set-rw get-rp set-rp
get-step-aw set-step-aw
get-start-af set-start-af get-end-af set-end-af)
;定义全局参数:
(define f-center (cons 300 300))
(define af0 30)
(define ap0 20)
(define rf 300)
(define rw 210)
(define rp 100)
(define step-aw 30)
(define start-af 0)
(define end-af 7720)
;设置/取得绘图全局参数:
(define (get-af0) af0)
(define (set-af0 a) (set! af0 a))
(define (get-ap0) ap0)
(define (set-ap0 a) (set! ap0 a))
(define (get-rf) rf)
(define (set-rf r) (set! rf r))
(define (get-rw) rw)
(define (set-rw r) (set! rw r))
(define (get-rp) rp)
(define (set-rp r) (set! rp r))
(define (get-step-aw) step-aw)
(define (set-step-aw a) (set! step-aw a))
(define (get-start-af) start-af)
(define (set-start-af a) (set! start-af a))
(define (get-end-af) end-af)
(define (set-end-af a) (set! end-af a))
;取得绘图点的X、Y坐标:
(define xp
(lambda (xw ap)
(+ xw (* rp (cos (degrees->radians ap))))))
(define yp
(lambda (yw ap)
(+ yw (* rp (sin (degrees->radians ap))))))
;计算滚轮圆心X、Y坐标:
(define xw
(lambda (af)
(+ (car f-center) (* (- rf rw) (cos (degrees->radians af))))))
(define yw
(lambda (af)
(+ (cdr f-center) (* (- rf rw) (sin (degrees->radians af))))))
;计算af、dlt-af、ap值:
(define af
(lambda (dlt-af)
(+ af0 dlt-af)))
(define dlt-af
(lambda (dlt-aw)
(/ (* rw dlt-aw) rf)))
(define ap
(lambda (dlt-aw)
(- ap0 dlt-aw)))
;组合坐标值为点值:
(define (get-p dlt-aw)
(cons (xp (xw (af (dlt-af dlt-aw))) (ap dlt-aw))
(yp (yw (af (dlt-af dlt-aw))) (ap dlt-aw))))
(define cur-aw
(lambda (af)
(/ (* af rf) rw)))
;绘制万花筒:
(define draw-artascope
(lambda (dc)
(let ([p1 (get-p af0)])
(do ([dlt-aw (cur-aw (+ af0 start-af)) (+ dlt-aw step-aw)])
((> dlt-aw (cur-aw (+ af0 end-af))) "结束画图。")
(let ([p2 (get-p dlt-aw)])
(begin
(send dc draw-lines (list p1 p2))
(set! p1 p2)))))))
;设置画布中心点为轨道圆心点:
;函数参数为函数,该函数参数取得画布的尺寸。
(define (set-f-center canvas-size)
(let-values ([(fx fy) (canvas-size)])
(set! f-center (cons (/ fx 2) (/ fy 2)))))
)
;===============================================================
;view-mail.rkt
;定义主界面视图:
;;;定义主界面:----------------------------------------------------------
(define main-frame
(new frame%
[label "万花筒(Artascope)"]
[width 800]
[height 600]
[border 5]))
;;;分割主界面:----------------------------------------------------------
;定义总面板:
(define panel-all
(new vertical-panel%
[parent main-frame]
[alignment '(left top)]
[stretchable-width #t]
[stretchable-height #t]))
;定义工具栏面板:
(define toolbars
(new horizontal-panel%
[parent panel-all]
[alignment '(left top)]
[stretchable-width #f]
[stretchable-height #f]
[border 2]))
;定义工作区:
(define panel-work
(new horizontal-panel%
[parent panel-all]
[alignment '(center center)]))
;定义画布面板:
(define panel-canvas
(new vertical-panel%
[parent panel-work]
[style '(border)]
[alignment '(left top)]
[border 10]))
;定义绘图参数设置面板
(define panel-setting
(new vertical-panel%
[parent panel-work]
[alignment '(right top)]
[border 5]
[min-width 180]
[stretchable-width #f]))
;;;定义画布:--------------------------------------------------------------
(define canvas
(new canvas%
[parent panel-canvas]))
;;;引入视图控制程序:--------------------------------------------------
(include "control-main.rkt")
;;;定义菜单----------------------------------------------------------------
(define menubar
(new menu-bar%
[parent main-frame]))
;;程序菜单:
(define menu-prog
(new menu%
[label "程序"]
[parent menubar]))
(define menu-item-draw
(new menu-item%
[label "画图"]
[parent menu-prog]
[callback draw]))
(define menu-item-clear
(new menu-item%
[label "清空画布"]
[parent menu-prog]
[callback clear]))
(define separator-menu-item-1
(new separator-menu-item%
[parent menu-prog]))
(define menu-item-exit
(new menu-item%
[label "退出"]
[parent menu-prog]
[callback
(lambda (item event)
(send main-frame on-exit))]))
;;帮助菜单:
(define menu-help
(new menu%
[label "帮助"]
[parent menubar]))
(define menu-item-help
(new menu-item%
[label "使用指南"]
[parent menu-help]
[callback help]))
(define menu-item-about
(new menu-item%
[label "关于"]
[parent menu-help]
[callback help]))
;;;定义工具栏按钮:----------------------------------------------------
(define toolbar-general
(new horizontal-panel%
[parent toolbars]
[alignment '(left top)]
[stretchable-width #f]
[stretchable-height #f]))
(define button-draw
(new button%
[parent toolbar-general]
[label "画图"]
[callback draw]))
(define button-clear
(new button%
[parent toolbar-general]
[label "清空画布"]
[callback clear]))
(define button-help
(new button%
[parent toolbar-general]
[label "关于此程序"]
[callback help]))
;;;定义绘图参数设置控件:--------------------------------------------
;轨道参数:
(define group-box-panel-frame
(new group-box-panel%
(parent panel-setting)
(label "轨道参数")
(alignment (list 'right 'top))
(stretchable-height #f)))
(define text-field-af0
(new text-field%
(parent group-box-panel-frame)
(label "轨道圆起始角")
(horiz-margin 5)
(min-width 165)
(stretchable-width #f)
(init-value (number->string (get-af0)))))
(define text-field-rf
(new text-field%
(parent group-box-panel-frame)
(label "轨道圆半径")
(horiz-margin 5)
(min-width 150)
(stretchable-width #f)
(init-value (number->string (get-rf)))))
(define text-field-start-af
(new text-field%
(parent group-box-panel-frame)
(label "轨道起始角")
(horiz-margin 5)
(min-width 150)
(stretchable-width #f)
(init-value (number->string (get-start-af)))))
(define text-field-end-af
(new text-field%
(parent group-box-panel-frame)
(label "轨道结束角")
(horiz-margin 5)
(min-width 150)
(stretchable-width #f)
(init-value (number->string (get-end-af)))))
;滚轮参数:
(define group-box-panel-wheel
(new group-box-panel%
(parent panel-setting)
(label "滚轮参数")
(alignment (list 'right 'top))
(stretchable-height #f)))
(define text-field-ap0
(new text-field%
(parent group-box-panel-wheel)
(label "绘制点起始角")
(horiz-margin 5)
(min-width 165)
(stretchable-width #f)
(init-value (number->string (get-ap0)))))
(define text-field-rw
(new text-field%
(parent group-box-panel-wheel)
(label "滚轮半径")
(horiz-margin 5)
(min-width 135)
(stretchable-width #f)
(init-value (number->string (get-rw)))))
(define text-field-rp
(new text-field%
(parent group-box-panel-wheel)
(label "绘制点半径")
(horiz-margin 5)
(min-width 150)
(stretchable-width #f)
(init-value (number->string (get-rp)))))
(define text-field-step-aw
(new text-field%
(parent group-box-panel-wheel)
(label "滚轮角步距")
(horiz-margin 5)
(min-width 150)
(stretchable-width #f)
(init-value (number->string (get-step-aw)))))
;==========================================================
;control-main.rkt
;main视图的控制程序:
;;;取得并设置绘图参数值(绘图面板函数):---------------------------------
#|
af0 ap0
rf rw rp
step-aw
start-af end-af
|#
(define (set-draw-parameter)
(set-af0 (string->number (send text-field-af0 get-value)))
(set-ap0 (string->number (send text-field-ap0 get-value)))
(set-rf (string->number (send text-field-rf get-value)))
(set-rw (string->number (send text-field-rw get-value)))
(set-rp (string->number (send text-field-rp get-value)))
(set-step-aw (string->number (send text-field-step-aw get-value)))
(set-start-af (string->number (send text-field-start-af get-value)))
(set-end-af (string->number (send text-field-end-af get-value))))
;;;菜单命令/工具栏执行程序-----------------------------------------------------
;绘制万花筒:
(define (draw menu-item event)
(set-draw-parameter);设置绘图参数
(set-f-center (lambda () (send canvas get-client-size)));设置轨道中心点
(draw-artascope (send canvas get-dc)))
;清空画布:
(define (clear menu-item event)
(send canvas refresh))
;显示关于对话框:
(define (help menu-item event)
(message-box "关于万花筒程序"
"万花筒程序:一个模拟万花筒的程序,用Racket编写。\n
本程序尽量全面展示了Racket语言GUI编程方式,以及基本的画布绘图操作。\n
作者:Racket"
main-frame
'(ok caution)))
源代码开源在Github上:https://github.com/OnRoadZy/artascope.git
====================== End
用Racket语言写了一个万花筒的程序的更多相关文章
- 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊
花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...
- C语言写了一个socket client端,适合windows和linux,用GCC编译运行通过
////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o c1 c1 ...
- C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过
////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o s1 s1 ...
- 用Go语言写了一个电脑搜索文件的小东西
package main import ( "bytes" "fmt" "os" "os/exec" "pat ...
- 在Seismic.NET下用最少的语句写出一个剖面显示程序
用Seismic.NET开发地震剖面显示程序可以节省大量的时间,下面的代码展开了如何用最少的代码显示一个SEGY文件. // 用一行语句把 reader, pipeline, view 和 plot ...
- socketserver模块写的一个简单ftp程序
一坨需求... 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 (cd) ...
- 使用python写的一个代码统计程序
# encoding="utf-8" """ 统计代码行数 """ import sys import os def c ...
- 分享下自己写的一个微信小程序请求远程数据加载到页面的代码
1 思路整理 就是页面加载完毕的时候 请求远程接口,然后把数据赋值给页面的变量 ,然后列表循环 2 js相关代码 我是改的 onload函数 /** * 生命周期函数--监听页面加载 */ on ...
- 自己写的一个多应用程序多目录的Makefile
DIR_INC = ./includeDIR_SRC = ./srcDIR_OBJ = ./objDIR_BIN = ./binINCLUDES = -I${DIR_INC} -I.CC => ...
随机推荐
- cogs1341 永无乡
cogs1341 永无乡 打了一发替罪羊树. 鬼故事:替罪羊树去掉重构(变成裸的二叉排序树)依然跑得过= = 启发式合并.每次把小的里面所有东西往大的里面一丢,每个点最多被丢\(log_2n\)次(丢 ...
- 《Node.js 包教不包会》
<Node.js 包教不包会> 为何写作此课程 在 CNode(https://cnodejs.org/) 混了那么久,解答了不少 Node.js 初学者们的问题.回头想想,那些问题所需要 ...
- ubuntu 16.04 安装php 5 6等版本
//加入ppa $ sudo add-apt-repository ppa:ondrej/php $ sudo apt-get update //安装5.6 $ sudo apt- //安装7 $ s ...
- Android 7.1.1系统源码下载、编译、刷机-Nexus 6实战
想成为一位合格的Android程序员或者一位Android高级工程师是十分有必要知道Android的框架层的工作原理,要知道其工作原理那么就需要阅读Android的源代码. 想要阅读Android的源 ...
- Linux的10个最危险的命令
Linux命令行佷有用.很高效,也很有趣,但有时候也很危险,尤其是在你不确定你自己在正在做什么时候. 这篇文章将会向你介绍十条命令,但你最好不要尝试着去使用. 当然,以下命令通常都是在root权限下才 ...
- Python不生成HTMLTestRunner报告-转载学习
1.问题:Python中同一个.py文件中同时用unittest框架和HtmlReport框架后,HtmlReport不被执行. 2.为什么?其实不是HtmlReport不被执行,也不是HtmlRep ...
- NOIP2018出征策
蒟蒻的风之旅人即将退役,现在分享一下退休前的故事 首先,经过这么多时间的划水训练,我成功从一个萌新变成了一个蒟蒻.我学会了各种奇怪玄学的算法,比如说昨天老师讲的NOIP第三题通用的算法,叫做XG算法, ...
- Kubernetes v1.10----部署kubernetes-dashboard v1.83
Kubernetes v1.10----部署kubernetes-dashboard v1.83 1.下载 kubernetes-dashboard yaml文件 #因为文件中的image指定的是谷 ...
- 转:为什么说招到合适的人比融到钱更加重要 - Hiring Great Talent is More Important Than Fund Raising
我在猎头行业工作了 20 多年,一直在帮助创业公司招聘优秀的人才.我服务过的客户既有 VC 投资的初创企业,也有即将 IPO 的公司.我和 200 多个 VC 合作过,也见过 300 多个客户失败的案 ...
- Beta发布-----欢迎来怼团队
欢迎来怼项目小组—Beta发布展示 一.小组成员 队长:田继平 成员:葛美义,王伟东,姜珊,邵朔,阚博文 ,李圆圆 二.文案+美工展示 链接:http://www.cnblogs.com/js2017 ...