forked from unknwon/the-way-to-go_ZH_CN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
polar_to_cartesian.go
executable file
·102 lines (91 loc) · 2.18 KB
/
polar_to_cartesian.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// polartocartesian.go
package main
import (
"bufio"
"fmt"
"math"
"os"
"runtime"
"strconv"
"strings"
)
type polar struct {
radius float64
Θ float64
}
type cartesian struct {
x float64
y float64
}
const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n"
var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit."
func init() {
if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { // Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D")
}
}
func main() {
questions := make(chan polar)
defer close(questions)
answers := createSolver(questions)
defer close(answers)
interact(questions, answers)
}
func createSolver(questions chan polar) chan cartesian {
answers := make(chan cartesian)
go func() {
for {
polarCoord := <-questions
Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians
x := polarCoord.radius * math.Cos(Θ)
y := polarCoord.radius * math.Sin(Θ)
answers <- cartesian{x, y}
}
}()
return answers
}
func interact(questions chan polar, answers chan cartesian) {
reader := bufio.NewReader(os.Stdin)
fmt.Println(prompt)
for {
fmt.Printf("Radius and angle: ")
line, err := reader.ReadString('\n')
if err != nil {
break
}
line = line[:len(line)-1] // chop of newline character
if numbers := strings.Fields(line); len(numbers) == 2 {
polars, err := floatsForStrings(numbers)
if err != nil {
fmt.Fprintln(os.Stderr, "invalid number")
continue
}
questions <- polar{polars[0], polars[1]}
coord := <-answers
fmt.Printf(result, polars[0], polars[1], coord.x, coord.y)
} else {
fmt.Fprintln(os.Stderr, "invalid input")
}
}
fmt.Println()
}
func floatsForStrings(numbers []string) ([]float64, error) {
var floats []float64
for _, number := range numbers {
if x, err := strconv.ParseFloat(number, 64); err != nil {
return nil, err
} else {
floats = append(floats, x)
}
}
return floats, nil
}
/* Output:
Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui
t.
Radius and angle: 12.5 90
Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50
Radius and angle: ^Z
*/