Nov 19
CGH,计算机生成全息,就是可以把入射光的相位信息保存下来的东西。目前网上介绍这个东西的文章大多以论文(而且都是要钱的…)的形式出现,不利于我等民间人士访问。正好这几天由于学习上的需要写了一个二维 CGH 的程序。大家都知道光学的全息就是让物光通过一组透镜产生傅立叶变换,然后用一束参考光干涉来记录,所以在 CGH 里只要对物做傅立叶变换,然后记录变换结果就行了。具体步骤如下:
- 把物做成图片
- 对图片做 FFT,生成一组复数
- 把复数编码成图片并保存
要还原时只需要从生成的图片里导出频域信息,并做 FFT 逆变换。

我这个程序比较弱智,我自己写了一个读写 bmp 文件的类,只能操作 windows 格式的 24 bit bmp,编码用了类似 Lohmann 的,用开孔的位置表示相位,孔的深浅表示幅度。用法为
holo -i <inputfile> [-o <outputfile>] [-w <site width>]
[-h <site height>] [-d <hole width>] [-r]
其中 site width 是每个孔能活动的宽度,site height 是孔的高度,hole width 是孔的宽度,site width - hole width 决定了相位的精度,而幅度的精度永远是 8 bit。
Share This
Sep 30
这是以前写的 texpng 程序的图形界面版,我把以前的 texpng.py 改写了一下(这是好听的说法,其实是剪切粘贴了一下),把转换过程抽象了一下,方便在图形界面里调用。和 texpng.py 一样,这个东西需要一个正常的 LaTeX 系统、dvipng 和 Imagemagick,除此之外,图形库使用了 wxpython。用法就不废话了,GUI 啊同志们… 最后,那三个图标是 oslo 图标集中的,版权属于原作者。
对了,过几天大家可能会看到一个更牛逼的转换 TeX 的程序,不过不是在我这里~~ :-p
最后的最后,说点感想~~
- 在 Linux 下写程序太方便了,感觉 Linux 就是写程序用的~~。这两天狂用了 Mac OS X 之后,隆重宣布:宇宙里最好用的 PC 操作系统是配置好的 Linux~~
- 现在写个图形界面太方便了!这个小破程序是我三个小时攒的…
- 还没想好…
PS:这个程序在运行的的时候会覆盖当前目录下的 temp.png 文件(如果有的话),退出的时候把这个文件删除。
Share This
Sep 21
Google 了无数次,也找到了一些安装显卡驱动的方法,但在我的机器上就是不管用… 所以到现在还没有硬件加速,这个本来没什么,少一些特效而已,但是发现 OS X 里播放视频是需要硬件加速的…
大概研究了一下 OS X 下的程序,标准的 OS X 程序都是一个名字以 .app 结尾的文件夹,里边一般只有一个文件夹叫 Contents,这个程序的一切都在这个文件夹里,包括图标,配置(有些比较底层的会在 /Library 和 /System 里面放配制)语言文件等等。比较爽的是,OS X 和它里面的程序都是极端脚本化的,不仅配置一律是 xml,而且控件的摆放(!),图片的位置,dock 图标,甚至部分逻辑都是 xml,对于我们这些喜欢没事瞎改的人来说,这样的系统基本上就是天堂了~~。举个简单的例子,无论在什么操作系统里,只要有一个图形界面的文件管理器,你在里面新建一个目录的时候都有一个默认的目录名,比如在 Windows 里叫“新建文件夹”,这是被硬编码的,没有源代码的人改不了;在 OS X 里叫 untitled name,这个可以在 /System/Library/CoreServices/Contents/Resources/English.lproj 中修改,这个 .lproj 是一个语言文件,会被其他的 xml 调用。貌似现在达到这种境界的基本上就只有 wxWindow 了(用 xml 来摆控件)。
OS X 里面是有 python 的,不过是 2.3 版,严重不爽,于是装了一个 2.5(装好以后还要手动做符号连接…),开始考虑有什么程序可以写~~。想了半天,决定写一个批量删除语言文件的东西,把机器里的那些非人类语言都删掉,可以节省数百 MB 的硬盘~~,代码(用法看开头的注释):
#!/usr/bin/env python
#
# Usage:
# kill-lang.py app_list
#
# eg: kill-lang.py mail.app aquamacs.app
# ls -1 | awk '{print "\""$0"\""}' | xargs kill-lang.py
import os
import sys
import re
import shutil
ReservedLang = ["English", "zh_CN"]
if len(sys.argv) == 1:
usage()
sys.exit(1)
def usage():
print(' '.join(["Usage:", sys.argv[0],
"application_names (with \".app\")"]))
return
def handleRmError(function, path, excinfo):
sys.stderr.write(''.join(["Error deleting ", path, ", err:\n", str(excinfo), "\n"]))
def killLang(app):
# Get the path where language files are located.
AppResource = '/'.join([app, "Contents", "Resources"])
if not os.path.isdir(AppResource):
sys.stderr.write("This program dose not have a standard app structure.\n")
sys.exit(2)
AppSubs = os.listdir(AppResource)
Langs = []
for Sub in AppSubs:
if re.match(".*\.lproj$", Sub) != None:
Langs.append(Sub)
FullLangs = ['/'.join([AppResource, Lang]) for Lang in Langs]
for i in range(len(FullLangs)):
if not Langs[i][:-6] in ReservedLang:
print("".join(["Deleting ", Langs[i], "..."]))
shutil.rmtree(FullLangs[i], False, handleRmError)
return 0
def main():
for App in sys.argv[1:]:
App = os.path.abspath(App)
print App + ':'
if not os.path.isdir(App) or len(App) - App.rfind(".app") != 4:
print "Not an app, skipped"
continue
killLang(App)
return 0
sys.exit(main())
Share This
Sep 13
今天在网上乱逛,不小心看到一个自动代理配置脚本(就是传说中的 pac 文件),发现语法怎么就和 Java 那么像呢~~?Google 一番之后发现其实 pac 就是一个 Javascript 函数,名叫 FindProxyForURL。它接收两个参数,url 和 host,都是字符串。url 是浏览器将要进入的地址,host 就是地址中 :// 和第一个 / 之间的部分。返回值为一个字符串,有三种情况:
- 直接连接,不经过代理,返回
"DIRECT"
- 经过代理,返回
"PROXY host:port“
- 经过 socks 服务器,返回
"SOCKS host:port“
有了这些规则,我们就可以随意加入逻辑,一劳永逸地解决是否使用代理,何时使用代理,使用什么代理等一系列重大问题。比如,我要对 blogspot 使用72.14.219.190,其他某些倒霉的地址使用 Tor,剩下的碌碌无为的地址不使用代理,就可以用下面这个 pac。
function FindProxyForURL(url, host)
{
url = url.toLowerCase();
host = host.toLowerCase();
if(dnsDomainIs(host, ".blogspot.com"))
return "PROXY 72.14.219.190:80";
if(dnsDomainIs(host, ".wikipedia.org") ||
dnsDomainIs(host, ".technorati.com")
)
return "SOCKS 127.0.0.1:9050";
return "DIRECT";
}
Reference: http://wp.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html#dnsDomainIs。Netscape 真是有长者风范啊~~
Share This
Aug 06
写了一个用来搞笑的 python 程序,可以随机地按照一定的语法生成句子。若干时间前写过一个功能差不多的程序,但是比较傻逼。
这个程序使用了 recursive transition networks 来表示一些简单的语法,目前可以递归地生成主语从句和宾语从句,并组合成完整的句子。看一些例子:
- The fool which reluctantly rocks unwillingly eats a book.
- The silly man that is silly unwillingly kicks a book which finally pisses.
- A book reluctantly eats a bug that is red.
- A man unwillingly sucks.
- The piece of shit that happily runs reluctantly kicks a bug.
:-p 词表里本来还有一个 fucking 的,考虑到这里的都是文化人,删了。代码在最后。
另外,Vincent 在 The slow downfall of Emacs 里写道 Emacs 在编辑器中的 popularity 排名正在降低。在几年前,编辑器的 top two 永远是 Vi/Vim 和 Emacs,但是现在 Emacs 竟然落在了 GEdit 和 Kite 之后(这帮傻逼都是怎么想的?!),到底是为什么?Vincent 在最后写道:“Why is that? Not pretty enough? Too powerful for the simple needs of the new users that Ubuntu brought to the Linux world?”
Continue reading »
Share This
Jul 28
看到了 Cheng Meng 的那个 Youtube downloader,由于对 Ruby 的无知,一点也看不懂,所以就参考 DownloadYoutube video with GAWK 用 python 自己写了一个。与 Cheng Meng 那个不同,我这个只负责把视频文件 url 打印出来。用法是 youtube-url.py video-id 所以要下载 id为 qNKtKm3SXvs 的视频,可以用这个命令
wget -O video.flv `youtube-url.py qNKtKm3SXvs`
youtube-url.py 的代码:
Continue reading »
Share This
Jul 20
才知道原来在多文件编译时 c++ 类模板的声明和定义一定包含在同一个文件里。
以前写 Game of Life 的时候写了一个动态二维数组的模板,当时的文件是这样包含的:
template<class T> class TMatrix
{
};
#include “matrix.cpp”
今天又用到了这个类,看这个文件包含不爽,改成了常规的
// matrix.hpp
template<class T> class TMatrix
{
// Declarations...
};
// matrix.cpp
#include "matrix.cpp"
... // Definitions
然后在主程序里引用了一个成员函数
// main.cpp
#include "matrix.hpp"
int main()
{
TMatrix<int> Matrix;
Matrix.row();
return 0;
}
编译:g++ -g main.cpp matrix.cpp
呜呼!出错了!说 TMatrix<int>::row() 只是声明了,没有定义。把 matrix 里的文件包含改成原来那个样子,然后只编译 main.cpp 就没问题了。百思不得其解,后来在 CSDN 上找到了这个。理论上,只要在模板声明前加上 export 关键字,然后用常规的多文件编译方法就可以,但是目前大部分编译器都不支持这个关键字。g++ 说“目前尚未实现,忽略”,真够直接的…
Share This
Jul 20
写了个简单的 elisp 函数 unfill-buffer,用来去掉当前 buffer 的所有单独的换行。
[coolcode lang=”lisp” download=”unfill-buffer.el”]
(defun unfill-buffer ()
“Unfill current buffer.”
(interactive “”)
(setq m (point-marker))
(beginning-of-buffer)
(while (re-search-forward “\\([^ ]+\\) *
*\\([^ ]\\)” nil t)
(replace-match “\\1\\2″))
(set-marker m 0 (current-buffer)))
[/coolcode]
Share This
Recent Comments