1. 程式人生 > >Go 語言: 極坐標與笛卡爾坐標的互轉

Go 語言: 極坐標與笛卡爾坐標的互轉

go golang polar

本文記錄使用 Go 語言實現 RESTful 的點坐標的轉換。

極坐標與笛卡爾坐標的數學關系

假設同一個點使用極坐標表示為 (ρ, θ), 使用笛卡爾坐標表示為(x,y),那麽,這些數學符號之間,有如下關系

x = ρ* Cosθ

y = ρ* Sinθ

ρ= Sqrt(x*x+y*y)

θ = Arctan(x/y)


Go語言實現

/*
* @Author: coolwp.com
* @Date: 2017-09-12 16:25:34
* @Last Modified by: suifengtec
* @Last Modified time: 2017-09-12 16:41:35
**/
/*
go build -o a.exe  main.go
*/
package main

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"math"
	"net/http"
	"strconv"
	"strings"
)

type DotJ struct {
	R float64 `json:"r"`
	A float64 `json:"a"`
}

type DotD struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
}

/*type DotJs []DotJ
type DotDs []DotD*/

/*
http://127.0.0.1:6688/d/12/5
{"r":13,"a":22.61986}
*/
func doD(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	errV := 0
	x, errX := strconv.ParseFloat(strings.TrimSpace(vars["x"]), 64)
	y, errY := strconv.ParseFloat(strings.TrimSpace(vars["y"]), 64)

	if errX != nil {
		fmt.Println("第1個值x輸入錯誤!")
		errV = 1
	} else {
		if errY != nil {
			fmt.Println("第2個值Y輸入錯誤!")
			errV = 2
		}
	}

	if errV == 0 {
		w.Header().Set("Content-Type", "application/json")

		r := math.Sqrt(x*x + y*y)
		a := math.Atan(y / x)
		a = hudu2jiaodu(a)

		r = toFixed(r, 5)
		a = toFixed(a, 5)

		dotJ := DotJ{R: r, A: a}
		json.NewEncoder(w).Encode(dotJ)

	} else {
		w.WriteHeader(404)
		fmt.Println("error:404")
	}
}

//極坐標轉換為笛卡爾坐標
/*
http://127.0.0.1:6688/j/13/22.61986
{"x":12,"y":5}

*/
func doJ(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	errV := 0

	rr, errR := strconv.ParseFloat(strings.TrimSpace(vars["r"]), 64)
	aa, errA := strconv.ParseFloat(strings.TrimSpace(vars["a"]), 64)

	if errR != nil {
		fmt.Println("第1個值x輸入錯誤!")
		errV = 1
	} else {
		if errA != nil {
			fmt.Println("第2個值Y輸入錯誤!")
			errV = 2
		}
	}

	if errV == 0 {
		w.Header().Set("Content-Type", "application/json")
		aV := jiaodu2hudu(aa)
		x := rr * math.Cos(aV)
		y := rr * math.Sin(aV)

		x = toFixed(x, 5)
		y = toFixed(y, 5)
		dotD := DotD{X: x, Y: y}
		json.NewEncoder(w).Encode(dotD)

	} else {
		w.WriteHeader(404)
		fmt.Println("error:404")
	}
}

func httpHandler() {
	myRouter := mux.NewRouter().StrictSlash(true)
	// 笛卡爾坐標轉換為極坐標
	myRouter.HandleFunc("/d/{x}/{y}", doD)
	// 極坐標轉換為笛卡爾坐標
	myRouter.HandleFunc("/j/{r}/{a}", doJ)
	log.Fatal(http.ListenAndServe(":6688", myRouter))
}

/*======================================================*/
func jiaodu2hudu(jiaodu float64) float64 {

	return jiaodu * math.Pi / 180
}
func hudu2jiaodu(hudu float64) float64 {

	return hudu * 180 / math.Pi
}

func round(num float64) int {
	return int(num + math.Copysign(0.5, num))
}

func toFixed(num float64, precision int) float64 {
	output := math.Pow(10, float64(precision))
	return float64(round(num*output)) / output
}

func main() {
	httpHandler()
	/*fireNow()*/
}

/*DEV: CLI使用*/
func fireNow() {
	var (
		ρ,
		θ,
		x,
		y float64
	)
	methodType := 1
	fmt.Print("請選擇轉換方式:\n輸入1,表示需要從極坐標轉換為笛卡爾坐標;\n輸入2,表示需要從笛卡爾坐標轉換為極坐標\n?")
	fmt.Scan(&methodType)

	if methodType != 1 && methodType != 2 {
		fmt.Println("貌似你輸入的不是1,也不是2啊,搞哪樣?")
		fireNow()
	} else {
		switch methodType {

		//輸入1,表示需要從極坐標轉換為笛卡爾坐標;
		case 1:
			fmt.Println("請以極坐標格式輸入點的坐標(ρ和 θ之間用1個空格隔開,θ默認為弧度單位)?")
			fmt.Scan(&ρ, &θ)
			θ = jiaodu2hudu(θ)
			x = ρ * math.Cos(θ)
			y = ρ * math.Sin(θ)
			fmt.Printf("x = %f, y= %f\n", x, y)
		//輸入2,表示需要從笛卡爾坐標轉換為極坐標
		case 2:

			fmt.Println("請以笛卡爾坐標格式輸入點的坐標(x和y之間用1個空格隔開, x不能為0)?")
			fmt.Scan(&x, &y)
			ρ = math.Sqrt(x*x + y*y)
			θ = math.Atan(y / x)
			θ = hudu2jiaodu(θ)
			fmt.Printf("ρ= %f, θ= %f\n", ρ, θ)
		}
	}
}


笛卡爾坐標轉極坐標示例 URL

http://127.0.0.1:6688/d/12/5

將會返回

{"r":13,"a":22.61986}

極坐標轉笛卡爾坐標示例URL

http://127.0.0.1:6688/j/13/22.61986

將會返回

{"x":12,"y":5}

兩種轉換默認精確到小數點後5位。


Go 語言: 極坐標與笛卡爾坐標的互轉