练习 3.1: 如果f函数返回的是无限制的float64值,那么SVG文件可能输出无效的多边形元素(虽然许多SVG渲染器会妥善处理这类问题)。修改程序跳过无效的多边形。

练习 3.2: 试验math包中其他函数的渲染图形。你是否能输出一个egg box、moguls或a saddle图案?

练习 3.3: 根据高度给每个多边形上色,那样峰值部将是红色(#ff0000),谷部将是蓝色(#0000ff)。

练习 3.4: 参考1.7节Lissajous例子的函数,构造一个web服务器,用于计算函数曲面然后返回SVG数据给客户端。服务器必须设置Content-Type头部:

w.Header().Set("Content-Type", "image/svg+xml")
(这一步在Lissajous例子中不是必须的,因为服务器使用标准的PNG图像格式,可以根据前面的512个字节自动输出对应的头部。)允许客户端通过HTTP请求参数设置高度、宽度和颜色等参数。

// Surface computes an SVG rendering of a 3-D surface function.
package main import (
"fmt"
"math"
"net/http"
"strconv"
) var height,width float64 = 300 , 600
var cells float64= 100 // number of grid cells
var xyrange float64= 30.0 // axis ranges (-xyrange..+xyrange)
var xyscale float64= width / 2 / xyrange // pixels per x or y unit
var zscale float64= height * 0.4 // pixels per z unit
var angle float64= math.Pi / 6 // angle of x, y axes (=30°) var sin30, cos30 = math.Sin(angle), math.Cos(angle) // sin(30°), cos(30°) func main() { //http服务
http.HandleFunc("/",handle)
http.ListenAndServe("0.0.0.0:8000",nil)
}
func handle(w http.ResponseWriter,r *http.Request){
w.Header().Set("Content-Type", "image/svg+xml")
if err := r.ParseForm();err != nil{
return
}
//var height int
//var width int
for k,v := range r.Form{
if k == "height"{
h, _ := strconv.ParseFloat(v[0],64)
if h>0 {height = h}
}
if k == "width"{
w, _ := strconv.ParseFloat(v[0],64)
if w>0 {width = w}
}
}
xyscale = width / 2 / xyrange
zscale = height * 0.4
fmt.Fprintf(w,"<svg xmlns='http://www.w3.org/2000/svg' "+
"style='stroke: #ff0000; fill: #0000ff; stroke-width: 0.7' "+
"width='%d' height='%d'>", width, height)
for i := 0; i < int(cells); i++ {
for j := 0; j < int(cells); j++ {
ax, ay := corner(i+1, j)
bx, by := corner(i, j)
cx, cy := corner(i, j+1)
dx, dy := corner(i+1, j+1)
fmt.Fprintf(w,"<polygon points='%g,%g %g,%g %g,%g %g,%g'/>\n",
ax, ay, bx, by, cx, cy, dx, dy)
}
}
fmt.Fprintf(w,"</svg>") }
func corner(i, j int) (float64, float64) {
// Find point (x,y) at corner of cell (i,j).
x := xyrange * (float64(i)/cells - 0.5)
y := xyrange * (float64(j)/cells - 0.5) // Compute surface height z.
z := f(x, y) // Project (x,y,z) isometrically onto 2-D SVG canvas (sx,sy).
sx := width/2 + (x-y)*cos30*xyscale
sy := height/2 + (x+y)*sin30*xyscale - z*zscale
return sx, sy
} func f(x, y float64) float64 {
r := math.Hypot(x, y) // distance from (0,0)
return math.Sin(r) / r
}

  

最新文章

  1. 美国 ZIP Code 一览表
  2. 使用appium进行ios测试,启动inspector时遇到的问题(一)
  3. AngularJS实现单页应用的原理——路由(Route)
  4. SimpleDataFormat格式
  5. Arcgis-ModelBuilder和Python学习
  6. OC基础 NSData
  7. Java 多线程(二) 线程的实现
  8. 实现对Java配置文件Properties的读取、写入与更新操作
  9. 深入解读Promise对象
  10. 如何预览Github上的页面
  11. Yahoo的Yslow23条规则
  12. windows下pem转ppk
  13. canvas 实现飞碟射击游戏
  14. October 14th 2017 Week 41st Saturday
  15. UVa 12186 工人的请愿书(树形DP)
  16. php框架的制作原理
  17. bzoj 2762: [JLOI2011]不等式组——树状数组
  18. Java集合(4):Iterator(迭代器)
  19. EIGRP-8-路由器的邻接关系
  20. php_strip_whitespace和trim的搭配使用

热门文章

  1. 在 Ubuntu 16.04上安装 vsFTPd
  2. .NET Core 跨平台 串口通讯 ,Windows/Linux 串口通讯,flyfire.CustomSerialPort 的使用
  3. [leetcode.com]算法题目 - Remove Duplicates from Sorted List
  4. 【PHP】当mysql遇上PHP
  5. 栈(链式栈)----C语言
  6. SpringBoot启动过程分析
  7. 【ElasticSearch】:Windows下ElasticSearch+版本安装head
  8. iOS开发-仿微信图片分享界面实现
  9. postgresql-pg_prewarm数据预加载。
  10. 10分钟打造强大的gvim