func PolySpec2(c gospec.Context) { p := linear.Poly{ {-1, 0}, {-3, 0}, {0, 10}, {3, 0}, {1, 0}, {2, 1}, {-2, 1}, } c.Specify("Check that exterior and interior segments of a polygon are correctly identified.", func() { visible_exterior := []linear.Seg2{ linear.MakeSeg2(-1, 0, -3, 0), linear.MakeSeg2(2, 1, -2, 1), linear.MakeSeg2(3, 0, 1, 0), } visible_interior := []linear.Seg2{ linear.MakeSeg2(2, 1, -2, 1), linear.MakeSeg2(-3, 0, 0, 10), linear.MakeSeg2(0, 10, 3, 0), linear.MakeSeg2(-1, 0, -3, 0), linear.MakeSeg2(3, 0, 1, 0), } c.Expect(p.VisibleExterior(linear.Vec2{0, -10}), ContainsExactly, visible_exterior) c.Expect(p.VisibleInterior(linear.Vec2{0, 5}), ContainsExactly, visible_interior) }) }
func vecInsideConvexPoly(v linear.Vec2, p linear.Poly) bool { for i := range p { seg := p.Seg(i) if seg.Left(v) { return false } } return true }
// ExistsClearLos checks that there is a clear LoS bettween two points and // expands all polys in the room so that anything that might normally only clip // on a vertex will be guaranteed to block LoS. func (r *Room) ExistsClearLos(a, b linear.Vec2, epsilon float64) bool { los := linear.Seg2{a, b} var expandedPoly linear.Poly for _, wall := range r.Walls { expandPoly(wall, &expandedPoly) for i := range expandedPoly { seg := expandedPoly.Seg(i) if seg.DoesIsect(los) { return false } } } return true }
func expandPoly(in linear.Poly, out *linear.Poly) { if len(*out) < len(in) { *out = make(linear.Poly, len(in)) } for i := range *out { (*out)[i] = linear.Vec2{} } for i, v := range in { segi := in.Seg(i) (*out)[i] = (*out)[i].Add(v.Add(segi.Ray().Cross().Norm().Scale(8.0))) j := (i - 1 + len(in)) % len(in) segj := in.Seg(j) (*out)[i] = (*out)[i].Add(v.Add(segj.Ray().Cross().Norm().Scale(8.0))) } for i := range *out { (*out)[i] = (*out)[i].Scale(0.5) } }
func PolySpec1(c gospec.Context) { p := linear.Poly{ {0, 0}, {-1, 2}, {0, 1}, {1, 2}, } c.Specify("Check that exterior and interior segments of a polygon are correctly identified.", func() { visible_exterior := []linear.Seg2{ linear.MakeSeg2(-1, 2, 0, 1), linear.MakeSeg2(0, 1, 1, 2), } visible_interior := []linear.Seg2{ linear.MakeSeg2(0, 1, 1, 2), linear.MakeSeg2(1, 2, 0, 0), linear.MakeSeg2(0, 0, -1, 2), } c.Expect(p.VisibleExterior(linear.Vec2{0, 2}), ContainsExactly, visible_exterior) c.Expect(p.VisibleInterior(linear.Vec2{0.5, 1.4}), ContainsExactly, visible_interior) }) }
func PolySpec3(c gospec.Context) { p := linear.Poly{ {0, 0}, {0, 1}, {1, 1}, {1, 0}, } c.Specify("Check that Poly.Seg(i) returns the i-th segment.", func() { s0 := linear.MakeSeg2(0, 0, 0, 1) VecExpect(c, p.Seg(0).P, Equals, s0.P) VecExpect(c, p.Seg(0).Q, Equals, s0.Q) s1 := linear.MakeSeg2(0, 1, 1, 1) VecExpect(c, p.Seg(1).P, Equals, s1.P) VecExpect(c, p.Seg(1).Q, Equals, s1.Q) s2 := linear.MakeSeg2(1, 1, 1, 0) VecExpect(c, p.Seg(2).P, Equals, s2.P) VecExpect(c, p.Seg(2).Q, Equals, s2.Q) s3 := linear.MakeSeg2(1, 0, 0, 0) VecExpect(c, p.Seg(3).P, Equals, s3.P) VecExpect(c, p.Seg(3).Q, Equals, s3.Q) }) }