练习 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
}

  

[日常] Go语言圣经--浮点数习题的更多相关文章

  1. [日常] Go语言圣经--Channel习题

    练习 8.3: 在netcat3例子中,conn虽然是一个interface类型的值,但是其底层真实类型是*net.TCPConn,代表一个TCP连接.一个TCP连接有读和写两个部分,可以使用Clos ...

  2. [日常] Go语言圣经--JSON习题2

    练习 4.12: 流行的web漫画服务xkcd也提供了JSON接口.例如,一个 https://xkcd.com/571/info.0.json 请求将返回一个很多人喜爱的571编号的详细描述. 下载 ...

  3. [日常] Go语言圣经--Map习题

    练习 4.8: 修改charcount程序,使用unicode.IsLetter等相关的函数,统计字母.数字等Unicode中不同的字符类别. 练习 4.9: 编写一个程序wordfreq程序,报告输 ...

  4. [日常] Go语言圣经--复数,布尔值,字符串习题

    go语言圣经-复数 1.我们把形如a+bi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位.两种精度的复数类型:complex64和complex128,分别对应float3 ...

  5. [日常] Go语言圣经--接口约定习题

    Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...

  6. [日常] Go语言圣经-Panic异常,Recover捕获异常习题

    Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...

  7. [日常] Go语言圣经-匿名函数习题

    Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...

  8. [日常] Go语言圣经-错误,函数值习题

    Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...

  9. [日常] Go语言圣经-函数多返回值习题

    Go语言圣经-函数多返回值1.在Go中,一个函数可以返回多个值2.许多标准库中的函数返回2个值,一个是期望得到的返回值,另一个是函数出错时的错误信息3.如果一个函数将所有的返回值都显示的变量名,那么该 ...

随机推荐

  1. WPF用户控件库 嵌入外部(VLC)exe

    综合网上资源完成的自己的第一篇博客 ------------------------------------------------------------------------ 网上类似的贴子挺多 ...

  2. ovs stp

    环路拓扑 组成拓扑结构的脚本 构成连通脚本 ip netns add ns1 ovs-vsctl add-br br1 ovs-vsctl add-port br1 tap1 -- set Inter ...

  3. AJPFX:什么是止盈?什么是止损?

    在您进行外汇交易后,会碰到Take Profit(止盈)和 Stop Loss(止损)这两个词,均是用作控制风险的工具. 止盈(Take Profit):当单子达到预期的获利价格时锁定盈利.当订单在盈 ...

  4. eclipse代码提示javadoc背景为黑色框的解决办法

    我的eclipse是近期下载的oxygen版本.不知道怎么出现了一个这个问题,鼠标悬停指向代码时应该出现的代码提示解释框,全为黑色,看不到文字.如下图 经过验证,最终解决方法为window->G ...

  5. 一步步Cobol 400 上手自学入门教程01 - 基础概念

    先学习基础概念 1.COBOL字符:包含: User-defined words 用户定义字符 ŸSystem-names ŸReserved words 关键字 2.用户定义字符User-defin ...

  6. switch...case... 语句中的类型转换

    switch语句对case表达式的结果类型有如下要求: 要求case表达式的结果能转换为switch表示式结果的类型 并且如果switch或case表达式的是无类型的常量时,会被自动转换为此种常量的默 ...

  7. 桶排序和计数排序的理解实现和比较(Java)

    比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比较排序.在排序的最终结果里,元素之间的次序依赖于它们之间的比较.每个数都必须和其他数进行比较,才能确定自己的位置.比较排序的优势是 ...

  8. POJ 2421

    #include<iostream> #include<stdio.h> #define MAXN 500 #define inf 100000000 using namesp ...

  9. 【从0到1学Web前端】javascript中的ajax对象(一) 分类: JavaScript 2015-06-24 10:18 754人阅读 评论(1) 收藏

    现在最流行的获取后端的(浏览器从服务器)数据的方式就是通过Ajax了吧.今天就来详细的来学习下这个知识吧.如果使用ajax来访问后段的数据,浏览器和浏览器端的js做了那些工作呢?我做了一个图,请大家看 ...

  10. Chrome 的 Material Design Refresh UI初探

    今天Chrome自动升级到69.0.3497.92, 发现UI已经变成了"Material Design Refresh". Chrome 浏览器的页面标签已经不再像以往那样倾斜和 ...