added rect-circle intersection functions
This commit is contained in:
parent
620c551f70
commit
4c6d061455
32
geometry.go
32
geometry.go
|
@ -318,6 +318,16 @@ func (r Rect) Intersect(s Rect) Rect {
|
|||
return t
|
||||
}
|
||||
|
||||
// IntersectsCircle returns whether the Circle and the Rect intersect.
|
||||
//
|
||||
// This function will return true if:
|
||||
// - The Rect contains the Circle, partially or fully
|
||||
// - The Circle contains the Rect, partially of fully
|
||||
// - An edge of the Rect is a tangent to the Circle
|
||||
func (r Rect) IntersectsCircle(c Circle) bool {
|
||||
return c.IntersectsRect(r)
|
||||
}
|
||||
|
||||
// Circle is a 2D circle. It is defined by two properties:
|
||||
// - Radius float64
|
||||
// - Center vector
|
||||
|
@ -470,6 +480,28 @@ func (c Circle) Intersect(d Circle) Circle {
|
|||
}
|
||||
}
|
||||
|
||||
// IntersectsRect returns whether the Circle and the Rect intersect.
|
||||
//
|
||||
// This function will return true if:
|
||||
// - The Rect contains the Circle, partially or fully
|
||||
// - The Circle contains the Rect, partially of fully
|
||||
// - An edge of the Rect is a tangent to the Circle
|
||||
func (c Circle) IntersectsRect(r Rect) bool {
|
||||
// Checks if the c.Center is not in the diagonal quadrants of the rectangle
|
||||
var grownR Rect
|
||||
if (r.Min.X <= c.Center.X && c.Center.X <= r.Max.X) || (r.Min.Y <= c.Center.Y && c.Center.Y <= r.Max.Y) {
|
||||
// 'grow' the Rect by c.Radius in each diagonal
|
||||
grownR = Rect{
|
||||
Min: r.Min.Sub(V(c.Radius, c.Radius)),
|
||||
Max: r.Max.Add(V(c.Radius, c.Radius)),
|
||||
}
|
||||
|
||||
return grownR.Contains(c.Center)
|
||||
}
|
||||
// The center is in the diagonal quadrants
|
||||
return c.Center.To(r.Min).Len() <= c.Radius || c.Center.To(r.Max).Len() <= c.Radius
|
||||
}
|
||||
|
||||
// Matrix is a 2x3 affine matrix that can be used for all kinds of spatial transforms, such
|
||||
// as movement, scaling and rotations.
|
||||
//
|
||||
|
|
|
@ -576,3 +576,73 @@ func TestCircle_Intersect(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRect_IntersectsCircle(t *testing.T) {
|
||||
type fields struct {
|
||||
Min pixel.Vec
|
||||
Max pixel.Vec
|
||||
}
|
||||
type args struct {
|
||||
c pixel.Circle
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): no overlap",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(1, pixel.V(50, 50))},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): circle contains rect",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(10, pixel.V(5, 5))},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): rect contains circle",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(1, pixel.V(5, 5))},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): circle overlaps one corner",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(1, pixel.V(0, 0))},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): circle overlaps two corner",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(11, pixel.V(0, 5))},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): circle overlaps one edge",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(1, pixel.V(0, 5))},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Rect.IntersectsCircle(): edge is tangent",
|
||||
fields: fields{Min: pixel.V(0, 0), Max: pixel.V(10, 10)},
|
||||
args: args{c: pixel.C(1, pixel.V(-1, 5))},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := pixel.Rect{
|
||||
Min: tt.fields.Min,
|
||||
Max: tt.fields.Max,
|
||||
}
|
||||
if got := r.IntersectsCircle(tt.args.c); got != tt.want {
|
||||
t.Errorf("Rect.IntersectsCircle() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue