0
点赞
收藏
分享

微信扫一扫

028-使用 go 绘制波浪曲面


1. 介绍

先来看看效果。


028-使用 go 绘制波浪曲面_go


图1 波浪曲面


这个曲面的函数是:


z=f(x,y)=10×sinx2+y2‾‾‾‾‾‾‾√x2+y2‾‾‾‾‾‾‾√ z = f ( x , y ) = 10 × s i n x 2 + y 2 x 2 + y 2

不妨令

r=x2+y2‾‾‾‾‾‾‾√ r = x 2 + y 2

,则


z=sin(r)r z = s i n ( r ) r

2. 原理和实现

下面代码路径是:​​src/gopl/basictypes/wave​​.

下面的实现里,为了能让图形更好的适应画布,使用了一些比例缩放。

  • 先假设有 100×100
  • 接下来用同样的方法,将小方格的另外三个顶点映射到画布中合适的位置。
  • 计算出小方格4个顶点在画布中的合适位置后,使用 svg 的 polygon 指令绘制出来。

package main

import (
"fmt"
"io"
"math"
"net/http"
)

const (
angle = math.Pi / 6
width = 1000
height = 1000
xyrange = 30.0 // x, y 变化范围,2*pi 一个周期,大约 2*2.4 个周期
xscale = width / 2 / xyrange
yscale = height / 2 / xyrange
cells = 100
)

var sin30, cos30 = math.Sin(angle), math.Cos(angle)

func draw(w io.Writer) {
fmt.Fprintf(w, "<svg xmlns='http://www.w3.org/2000/svg' style='stroke: grey; fill: white; stroke-width: 0.7' width='1000' height='1000'>\n")
for i := 0; i < cells; i++ {
for j := 0; j < cells; j++ {

//

xx1, yy1 := corner(i, j)
xx2, yy2 := corner(i, j+1)
xx3, yy3 := corner(i+1, j+1)
xx4, yy4 := corner(i+1, j)
fmt.Fprintf(w, "<polygon points='%g,%g %g,%g %g,%g %g,%g' />\n",
xx1, yy1,
xx2, yy2,
xx3, yy3,
xx4, yy4)
}
}
fmt.Fprintf(w, "</svg>\n")
}

// 计算第 (i, j) 个小方块的角点坐标
func corner(i, j int) (float64, float64) {
// 将 i, j 映射到 xyrange 这个范围,然后再计算坐标
x := xyrange * (float64(i)/cells - 0.5)
y := xyrange * (float64(j)/cells - 0.5)
xx, yy := project(x, y, f(x, y))
return width/2 + xx*xscale, height/2 + yy*yscale
}

func project(x, y, z float64) (float64, float64) {
xx := x*cos30 - y*cos30
yy := x*sin30 + y*sin30 - z
return xx, yy
}

func f(x float64, y float64) float64 {
r := math.Hypot(x, y)
z := math.Sin(r) / r
return 10 * z
}

func handle(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/svg+xml")
draw(w)
}

func main() {
http.HandleFunc("/", handle)
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Printf("%v", err)
}
}

3. 总结

  • 掌握浮点数的应用
  • 了解 svg

练习:

  1. 尝试修改曲面的颜色。
  2. 尝试添加更多的颜色。


028-使用 go 绘制波浪曲面_xml_02


图2 带颜色的热力图



举报

相关推荐

0 条评论