51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package main
|
|
|
|
import "fmt"
|
|
|
|
type xy struct {
|
|
x, y float64
|
|
}
|
|
|
|
type closedPoly struct {
|
|
name string
|
|
vert []xy
|
|
}
|
|
|
|
func inside(pt xy, pg closedPoly) bool {
|
|
if len(pg.vert) < 3 {
|
|
return false
|
|
}
|
|
in := rayIntersectsSegment(pt, pg.vert[len(pg.vert)-1], pg.vert[0])
|
|
for i := 1; i < len(pg.vert); i++ {
|
|
if rayIntersectsSegment(pt, pg.vert[i-1], pg.vert[i]) {
|
|
in = !in
|
|
}
|
|
}
|
|
return in
|
|
}
|
|
|
|
func rayIntersectsSegment(p, a, b xy) bool {
|
|
return (a.y > p.y) != (b.y > p.y) &&
|
|
p.x < (b.x-a.x)*(p.y-a.y)/(b.y-a.y)+a.x
|
|
}
|
|
|
|
var tpg = []closedPoly{
|
|
{"square", []xy{{0, 0}, {10, 0}, {10, 10}, {0, 10}}},
|
|
{"square hole", []xy{{0, 0}, {10, 0}, {10, 10}, {0, 10}, {0, 0},
|
|
{2.5, 2.5}, {7.5, 2.5}, {7.5, 7.5}, {2.5, 7.5}, {2.5, 2.5}}},
|
|
{"strange", []xy{{0, 0}, {2.5, 2.5}, {0, 10}, {2.5, 7.5}, {7.5, 7.5},
|
|
{10, 10}, {10, 0}, {2.5, 2.5}}},
|
|
{"exagon", []xy{{3, 0}, {7, 0}, {10, 5}, {7, 10}, {3, 10}, {0, 5}}},
|
|
}
|
|
|
|
var tpt = []xy{{1, 2}, {2, 1}}
|
|
|
|
func main() {
|
|
for _, pg := range tpg {
|
|
fmt.Printf("%s:\n", pg.name)
|
|
for _, pt := range tpt {
|
|
fmt.Println(pt, inside(pt, pg))
|
|
}
|
|
}
|
|
}
|