Adron
3/10/2019 - 9:00 PM

Rendering an SVG and more maths!

Rendering an SVG and more maths!

package main

import (
	"fmt"
	"io/ioutil"
	"math"
	"strconv"
)

const (
	width, height = 600, 600
	cells         = 100
	xyrange       = 30.0
	xyscale       = width / 2 / xyrange
	zscale        = height * 0.4
	angle         = math.Pi / 6
)

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

func main() {

	var outputResult string

	outputResult = "<svg xmlns='http://www.w3.org/2000/svg' " +
		"style='stroke: blue; fill: white; stroke-width: 0.7' " +
		"width='" + strconv.Itoa(width) + "' height='" + strconv.Itoa(height) + "'>"

	for i := 0; i < cells; i++ {
		for j := 0; j < 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)

			outputResult = outputResult + "<polygon points='" +
				ax + "," + ay +
				bx + "," + by +
				cx + "," + cy +
				dx + "," + dy +
				"'/>\n"
		}
	}
	outputResult = outputResult + "</svg>"
	fmt.Printf(outputResult)
	err := ioutil.WriteFile("surface-plot.svg", []byte(outputResult), 0644)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
}

func corner(i, j int) (string, string) {
	x := xyrange * (float64(i)/cells - 0.5)
	y := xyrange * (float64(j)/cells - 0.5)

	z := f(x, y)

	sx := width/2 + (x-y)*cos30*xyscale
	sy := height/2 + (x+y)*sin30*xyscale - z*zscale

	xResult := strconv.FormatFloat(sx, 'f', -1, 64)
	yResult := strconv.FormatFloat(sy, 'f', -1, 64)
	return xResult, yResult
}

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