簡體   English   中英

3D 等角投影的着色

[英]Coloring for 3D Isometric projection

問題是,基於以下程序https://github.com/adonovan/gopl.io/blob/master/ch3/surface/main.go

  1. 轉為web服務器,將SVG渲染為web頁面
  2. 給 SVG 上色,使峰為紅色,谷為藍色

我肯定第一部分是對的,我想我第二部分是對的,但顯然不是,但我不知道我哪里錯了。 請幫忙。

package main

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

const (
    cells   = 100         // number of grid cells
    xyrange = 30.0        // axis ranges (-xyrange..+xyrange)
    angle   = math.Pi / 6 // angle of x, y axes (=30°)
)

var height, width = 300, 600 // canvas size in pixels

var xyscale = width / 2 / xyrange  // pixels per x or y unit
var zscale = float64(height) * 0.4 // pixels per z unit

var sin30, cos30 = math.Sin(angle), math.Cos(angle) // sin(30°), cos(30°)

func main() {
    addr := ":8000"
    fmt.Printf("Visit\n  http://localhost%s/\n  http://localhost%[1]s/?height=600&width=1200\n", addr)

    //http server
    http.HandleFunc("/", handle)
    http.ListenAndServe(addr, nil)
}

func handle(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "image/svg+xml")
    if err := r.ParseForm(); err != nil {
        return
    }
    for k, v := range r.Form {
        if k == "height" {
            h, _ := strconv.Atoi(v[0])
            if h > 0 {
                height = h
            }
        }
        if k == "width" {
            w, _ := strconv.Atoi(v[0])
            if w > 0 {
                width = w
            }
        }
    }

    xyscale = width / 2 / xyrange
    zscale = float64(height) * 0.4
    fmt.Fprintf(w, "<svg xmlns='http://www.w3.org/2000/svg' "+
        "style='stroke: grey; stroke-width: 0.7' "+
        "width='%d' height='%d'>", width, 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)
            r, g, b := getColor(i, j)
            fmt.Fprintf(w, "<polygon points='%g,%g %g,%g %g,%g %g,%g' fill='#%x%x%x'/>\n",
                ax, ay, bx, by, cx, cy, dx, dy, r, g, b)
        }
    }
    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 := float64(width/2) + (x-y)*cos30*float64(xyscale)
    sy := float64(height/2) + (x+y)*sin30*float64(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
}

func getColor(i, j int) (int, int, int) {
    // Find point (x,y) at middle of corner of cell (i,j) to cell (i+1,j+1).
    x := xyrange * (float64(i)/cells + 0.5/cells - 0.5)
    y := xyrange * (float64(j)/cells + 0.5/cells - 0.5)

    // Compute surface height z.
    z := math.Hypot(x, y) // distance from (0,0)
    v := int(math.Sin(z)*127) + 128
    r := v
    g := 0
    b := 255 - v
    return r, g, b
}

這是我得到的結果:

在此處輸入圖像描述

注意,雖然問題似乎是針對 Go,但實際上我要問的是getColor()算法。 不寫Go也能看懂/回答。

您的代碼使用格式動詞%x將十六進制值打印到 SVG 的fill屬性:

fmt.Fprintf(w, "<polygon points='%g,%g %g,%g %g,%g %g,%g' fill='#%x%x%x'/>\n",
                ax, ay, bx, by, cx, cy, dx, dy, r, g, b)

這會導致某些數字(如 0 和 1)被格式化為一個十六進制數字。 例如 RGB (254, 0, 1) 將被格式化為fe01 然后瀏覽器錯誤地呈現 colors。

將格式動詞更改為%02x以確保 RGB 始終使用兩個十六進制數字打印。

現在 RGB (254, 0, 1) 打印為fe0001 ,這是正確的十六進制顏色。

Output:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM