# -*- coding: utf-8 -*-
import pylab
from math import radians, sin, cos, tan
def make_bezier(p0, p1, p2, p3):
# ベジエ曲線の公式
# t: 0.0~1.0までの値 0.0のとき、始点をplotし、1.0のとき、終点をplotする。
def formula(t, p0, p1, p2, p3):
return ((1-t)**3)*p0 + (3*t)*((1-t)**2)*p1 + 3*(t**2)*(1-t)*p2 +(t**3)*p3
def _bezier(t):
return [formula(t, p0[i],p1[i],p2[i],p3[i]) for i in (0, 1)]
return _bezier
def transform(x, y, m):
return (x*m[0] + y*m[3] + m[6], \
x*m[1] + y*m[4] + m[7], \
x*m[2] + y*m[5] + m[8])
if __name__ == '__main__':
t = pylab.arange(0.0, 1.001, 0.01)
bazier = make_bezier((0, 0), (0, 3), (3, 0), (3, 3))
# 変換なし
m = (1, 0, 0, \
0, 1, 0, \
0, 0, 1)
coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
(xs,ys) = zip(*coordinates)
pylab.plot(xs, ys)
# 平行移動 (3, 3)
m = (1, 0, 0, \
0, 1, 0, \
3, 3, 1)
coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
(xs,ys) = zip(*coordinates)
pylab.plot(xs, ys)
# 拡大 (-1.5, -1.5) ※原点対照に反転し、1.5培する。
m = (-1.5, 0, 0, \
0, -1.5, 0, \
0, 0, 1)
coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
(xs,ys) = zip(*coordinates)
pylab.plot(xs, ys)
# 回転 60°
r = radians(60)
m = (cos(r), sin(r), 0, \
-sin(r), cos(r), 0, \
-5, 5, 1)
coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
(xs,ys) = zip(*coordinates)
pylab.plot(xs, ys)
# 傾斜 a=15° b=20°
a = radians(-15)
b = radians(-20)
m = (1, tan(a), 0, \
tan(b), 1, 0, \
-5, 5, 1)
coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))]
(xs,ys) = zip(*coordinates)
pylab.plot(xs, ys)
pylab.grid()
pylab.axis([-15, 15, -15, 15])
pylab.show()
2012年5月17日木曜日
[Python, pylab]how to transform graphics with 3-by-3 transformation matrix.
pylabでベジエ曲線が描けたので、今度は変換行列で、変換を行ってみます。
2012年5月16日水曜日
[Python,pylab]how to plot bezier curve.
pylabの実験のために、ベジエ曲線を描いてみました。
ベジエ曲線を描くためのメソッドを使用するのではなく、
数式で座標を計算してプロットしました。
>>> import pylab
>>> def bezier(p0, p1, p2, p3):
def f(t, p0, p1, p2, p3):
return ((1-t)**3)*p0 + (3*t)*((1-t)**2)*p1 + 3*(t**2)*(1-t)*p2 +(t**3)*p3
def _bezier(t):
return [f(t, p0[i],p1[i],p2[i],p3[i]) for i in (0, 1)]
return _bezier
>>> t = pylab.arange(0.0, 1.0, 0.01)
>>> f = bezier((2, 2), (3, 4), (4.5, 4), (5, 1.5))
>>> pylab.plot(*f(t))
>>> pylab.axis([0, 6, 0, 6])
>>> pylab.show()
確かにベジエ曲線が描けました。
ラベル:
bezier curve,
plot,
pylab,
python,
ベジエ
2012年3月8日木曜日
python mapserver-6.0.2 mapscript layerObj NameError
MapServerの調査をしています。
SWIG MapScript APIのpython版にバグがあるようです。
以下のようなコードを書くと、例外が発生します。
>>>import mapscript
>>>map = mapscript.mapObj('./x.map')
>>>layer = mapscript.layerObj(map)
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/site-packages/MapScript-6.0.2-py2.7-linux-x86_64.egg/mapscript.py", line 1381, in __init__
if args and len(args)!=0:
NameError: global name 'args' is not defined
mapscript.pyをのぞいてみると、確かに"args"という変数は未定義です。
class layerObj(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, layerObj, name, value)
__swig_getmethods__ = {}
# 略
def __init__(self, map = None):
this = _mapscript.new_layerObj(map)
try: self.this.append(this)
except: self.this = this
if 1:
if args and len(args)!=0: #'args' is not defined!
self.p_map=args[0]
else:
self.p_map=None
# 略
しょうがないので、以下のように修正し、python-mapscriptをインストールしなおしました。
class layerObj(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, layerObj, name, value)
__swig_getmethods__ = {}
# 略
def __init__(self, map = None):
this = _mapscript.new_layerObj(map)
try: self.this.append(this)
except: self.this = this
#if 1:
# if args and len(args)!=0: #'args' is not defined!
# self.p_map=args[0]
# else:
# self.p_map=None
self.p_map = map
# 略
これで一応動きました。
追記:
classObjのコンストラクターも同様に修正が必要でした。
あと、既知のバグみたいです。
MapServer Issue Tracker "MapScript classObj Error"
http://trac.osgeo.org/mapserver/ticket/3940
2012年2月23日木曜日
easy_install bad interpreter
pythonでモジュールのインストールに使う、“easy_install”をインストールして使おうとしたところ、
↓こんなエラーがでました。
$ sudo easy_install
-bash: /usr/local/bin/easy_install: .: bad interpreter: Permission denied
shebang(シェルスクリプトの1行目の#!で始まる行)を確認すると
#!.
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
__requires__ = 'setuptools==0.6c11'
import sys
from pkg_resources import load_entry_point
と、#!.になっていたので、pythonの実行ファイルのパスを指定したらエラーが起こらなくなりました。
$ sudo easy_install
error: No urls, filenames, or requirements specified (see --help)
なぜ、shebangがそんな風になっていたのか、原因は調べていません。
↓こんなエラーがでました。
$ sudo easy_install
-bash: /usr/local/bin/easy_install: .: bad interpreter: Permission denied
shebang(シェルスクリプトの1行目の#!で始まる行)を確認すると
#!.
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
__requires__ = 'setuptools==0.6c11'
import sys
from pkg_resources import load_entry_point
と、#!.になっていたので、pythonの実行ファイルのパスを指定したらエラーが起こらなくなりました。
$ sudo easy_install
error: No urls, filenames, or requirements specified (see --help)
なぜ、shebangがそんな風になっていたのか、原因は調べていません。
2012年2月21日火曜日
mysql-python MySQLdb ImportError: libmysqlclient_r.so.15
mysql-python(MySQLdb)をインストールして、以下のエラーが発生した場合、
共有オブジェクトにパスが通ってないのかもしれません。
その場合、ldconfigを使用して、当該shared objectにパスを通すと、動くようになります。
$ python
>>> import MySQLdb
Traceback (most recent call last):
File "", line 1, in
File "build/bdist.linux-i686/egg/MySQLdb/__init__.py", line 19, in
File "build/bdist.linux-i686/egg/_mysql.py", line 7, in
File "build/bdist.linux-i686/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory
>>>
$ sudo vi /etc/ld.so.conf
Include ld.so.conf.d/*.conf
/usr/local/lib
/usr/lib/mysql ←これを追加。
$ sudo ldconfig
$ python
>>> import MySQLdb
>>>
共有オブジェクトにパスが通ってないのかもしれません。
その場合、ldconfigを使用して、当該shared objectにパスを通すと、動くようになります。
$ python
>>> import MySQLdb
Traceback (most recent call last):
File "
File "build/bdist.linux-i686/egg/MySQLdb/__init__.py", line 19, in
File "build/bdist.linux-i686/egg/_mysql.py", line 7, in
File "build/bdist.linux-i686/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory
>>>
$ sudo vi /etc/ld.so.conf
Include ld.so.conf.d/*.conf
/usr/local/lib
/usr/lib/mysql ←これを追加。
$ sudo ldconfig
$ python
>>> import MySQLdb
>>>
2012年1月19日木曜日
python MySQLdb で取得したデータを Jinja2でrenderすると UnicodeDecodeError
MySQLから取得したデータをJinja2を使って出力する場合、
MySQLdbモジュールのconnect関数でConnectionオブジェクトを取得する際に、
use_unicodeとcharset引数を設定し、取得結果の文字列をunicodeで保持する必要があります。
API - Jinja2 2.7-dev documentation Unicode
http://jinja.pocoo.org/docs/api/#unicode
下記の記述があります。
訳:
MySQLdb User's Guide MySQLdb Functions and attributes
http://mysql-python.sourceforge.net/MySQLdb.html#functions-and-attributes
connect(parameters...)
use_unicode
charset
以下に実例を示します。
ASCII文字列ではない文字列を渡したので、UnicodeDecodeErrorが起きます。
言い換えると、文字列が渡されたときは、Unicodeに変換するために、x.decode('ascii')を試み、
結果、encodeがasciiでない場合は、UnicodeDecodeErrorが起きる。と言えそうです。
文字列はutf8でdecodeしてUnicodeで保持するように指示したので、
UnicodeDecodeErrorは起きません。
charset='utf-8'
にすると、例外が発生します。
***
上記はCentOS5.5で動作させた例なのですが、
同様のことをwindowsのeclipse/PyDevで行うと、
MySQLdb.connect関数でuse_unicode=Trueとしなくても、
UnicodeDecodeErrorは起きませんでした。
理由はわかりません。
MySQLdbモジュールのconnect関数でConnectionオブジェクトを取得する際に、
use_unicodeとcharset引数を設定し、取得結果の文字列をunicodeで保持する必要があります。
API - Jinja2 2.7-dev documentation Unicode
http://jinja.pocoo.org/docs/api/#unicode
下記の記述があります。
Jinja2 is using Unicode internally which means that you have to pass Unicode objects to the render function or bytestrings that only consist of ASCII characters.
訳:
Jinja2 の内部処理はUnicodeを使用しているので、render関数にはUnicodeオブジェクトかASCII文字のみからなるバイト文字列を渡す必要があります。
MySQLdb User's Guide MySQLdb Functions and attributes
http://mysql-python.sourceforge.net/MySQLdb.html#functions-and-attributes
connect(parameters...)
use_unicode
charset
以下に実例を示します。
$ python
Python 2.7.1 (r271:86832, Nov 10 2011, 09:26:52)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb as db
>>> import jinja2 as j2
>>> def get_rows_with(con):
... with con:
... cur = con.cursor()
... cur.execute("select * from test_table")
... rows = cur.fetchall()
... cur.close()
... return rows
...
>>> t = j2.Template('{% for row in rows %}{{ row[0] }} | {{ row[1] }}\n{% endfor %}')
>>> con = db.connect(host='localhost', db='test', user='test_user', passwd='xxxx')
>>> rows = get_rows_with(con)
>>> print t.render(rows=rows)
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "", line 1, in top-level template code
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
ASCII文字列ではない文字列を渡したので、UnicodeDecodeErrorが起きます。
言い換えると、文字列が渡されたときは、Unicodeに変換するために、x.decode('ascii')を試み、
結果、encodeがasciiでない場合は、UnicodeDecodeErrorが起きる。と言えそうです。
>>> con = db.connect(host='localhost', db='test', user='test_user', passwd='xxxx', use_unicode=True, charset='utf8') >>> rows = get_rows_with(con) >>> print t.render(rows=rows) 01 | あ 02 | い 03 | う 04 | え 05 | お
文字列はutf8でdecodeしてUnicodeで保持するように指示したので、
UnicodeDecodeErrorは起きません。
charset='utf-8'
にすると、例外が発生します。
***
上記はCentOS5.5で動作させた例なのですが、
同様のことをwindowsのeclipse/PyDevで行うと、
MySQLdb.connect関数でuse_unicode=Trueとしなくても、
UnicodeDecodeErrorは起きませんでした。
理由はわかりません。
2012年1月17日火曜日
mysql-python windows setup.py build
pythonがインストールされていて、MySQLサーバがインストールされていないマシンで、
mysql-pythonのMySQLdbモジュールを使いたいとき、
モジュールのセットアップには、Connector/Cが必要です。
【手順】
これで、ビルドする。
私の環境では、これで使えるようになりました。
mysql-pythonのMySQLdbモジュールを使いたいとき、
モジュールのセットアップには、Connector/Cが必要です。
【手順】
- Connector/Cをインストールする。
- MySQL-python-1.2.3.tar.gzをdownloadして展開する。
- setup_windows.pyのget_configの以下の部分を修正する。
metadata, options = get_metadata_and_options()
# 以下2行をコメントアウトし、1行追加
#serverKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, options['registry_key'])
#mysql_root, dummy = _winreg.QueryValueEx(serverKey,'Location')
mysql_root = 'C:\\Program Files (x86)\\MySQL\\MySQL Connector C 6.0.2' # Connector/Cのインストール先
>python setup.py build
私の環境では、これで使えるようになりました。
登録:
コメント (Atom)

