本节我们使用前面学过的 image 包来绘制 lissajous 曲线。
1. lissajous 曲线
数学上,利萨茹(Lissajous)曲线(又称利萨茹图形、李萨如图形或鲍迪奇(Bowditch)曲线)是两个沿着互相垂直方向的正弦振动的合成的轨迹。
图1 lissajous 曲线
1.1 数学定义
利萨茹曲线由以下参数方程定义:
{x(θ)=asin(θ)y(θ)=bsin(nθ+ϕ) { x ( θ ) = a sin ( θ ) y ( θ ) = b sin ( n θ + ϕ )
其中
0≤ϕ≤π2,n≥1 0 ≤ ϕ ≤ π 2 , n ≥ 1
n n 称为曲线的参数,是两个正弦振动的频率比。若比例为有理数,则 n=qpn=qp,参数方程可以写作:
⎧⎩⎨⎪⎪x(θ)=asin(pθ)y(θ)=bsin(qθ+ϕ)0≤θ≤2π { x ( θ ) = a sin ( p θ ) y ( θ ) = b sin ( q θ + ϕ ) 0 ≤ θ ≤ 2 π
其中 0≤ϕ≤π2p 0 ≤ ϕ ≤ π 2 p 。
1.2 特殊情况
- 若 a=b,n=1 ,则这besace是一个热罗诺双纽线。
图 1 是利萨茹曲线的例子,其中 ϕ=0 ϕ = 0 , a=b a = b , p=13 p = 13 , q=18 q = 18 . 图2 是 |p−q|=1 | p − q | = 1
图2
|p−q|=1
|
p
−
q
|
=
1
2. 使用 go 语言绘制 lissajous 图形
知道了了参数方程后,那就太简单了。只要我们控制好 p,q p , q
图2 使用 go 绘制的结果
- 程序
程序路径是gopl/tutorial/image/lissajous/lissajous1.go
// lissajous1.go
package main
import (
"image"
"image/color"
"image/png"
"math"
"os"
"strconv"
)
const (
size = 128
)
func main() {
p := 3.0
q := 4.0
phi := 0.0
if len(os.Args) >= 2 {
p, _ = strconv.ParseFloat(os.Args[1], 64)
}
if len(os.Args) >= 3 {
q, _ = strconv.ParseFloat(os.Args[2], 64)
}
if len(os.Args) >= 4 {
phi, _ = strconv.ParseFloat(os.Args[3], 64)
}
palett := []color.Color{color.RGBA{0xee, 0xee, 0xee, 0xff}, color.RGBA{0xff, 0, 0, 0xff}}
rec := image.Rect(0, 0, 2*size, 2*size)
img := image.NewPaletted(rec, palett)
s := float64(size - 10) // 比例缩放
for t := 0.0; t <= 2*math.Pi; t += 0.0001 {
x := math.Sin(p * t)
y := math.Sin(q*t + phi)
img.SetColorIndex(size+int(s*x+0.5), size+int(s*y+0.5), 1)
}
png.Encode(os.Stdout, img)
}
我们再来使用上面的程序绘图图 1 中的例子。
$ go run lissajous1.go 13 18 > a.png
图3
p=13,q=18
p
=
13
,
q
=
18
3. 总结
- 感受数学的魅力
- 进一步熟悉 go 语言强大的 image 包
练习:
- 自己完成 lissajous 曲线的绘制
- 尝试更多的参数