From ec7118e08f71e9c6ed29985283a655fd8974ddcf Mon Sep 17 00:00:00 2001 From: BuckarooBanzay Date: Mon, 2 Sep 2024 12:37:06 +0200 Subject: [PATCH] add `Area.Union()` --- area.go | 20 +++++++++++++++++++ area_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/area.go b/area.go index dcb1d39..2bb7a01 100644 --- a/area.go +++ b/area.go @@ -47,3 +47,23 @@ func (a *Area) Intersects(a2 *Area) bool { } return false } + +func (a *Area) Union(a2 *Area) *Area { + if !a.Intersects(a2) { + // no union possible + return nil + } + + return &Area{ + Pos1: NewPos( + max(a.Pos1.X(), a2.Pos1.X()), + max(a.Pos1.Y(), a2.Pos1.Y()), + max(a.Pos1.Z(), a2.Pos1.Z()), + ), + Pos2: NewPos( + min(a.Pos2.X(), a2.Pos2.X()), + min(a.Pos2.Y(), a2.Pos2.Y()), + min(a.Pos2.Z(), a2.Pos2.Z()), + ), + } +} diff --git a/area_test.go b/area_test.go index 36174f6..90b3511 100644 --- a/area_test.go +++ b/area_test.go @@ -32,3 +32,58 @@ func TestArea(t *testing.T) { assert.False(t, a2.Intersects(a)) assert.False(t, a.Intersects(a2)) } + +func TestAreaUnion(t *testing.T) { + // simple area set + a1 := types.NewArea( + types.NewPos(0, 0, 0), + types.NewPos(10, 10, 10), + ) + a2 := types.NewArea( + types.NewPos(0, 0, 0), + types.NewPos(5, 5, 5), + ) + u := a1.Union(a2) + assert.Equal(t, types.NewPos(0, 0, 0), u.Pos1) + assert.Equal(t, types.NewPos(5, 5, 5), u.Pos2) + + // area with offset + a1 = types.NewArea( + types.NewPos(2, 2, 2), + types.NewPos(10, 10, 10), + ) + a2 = types.NewArea( + types.NewPos(0, 0, 0), + types.NewPos(5, 6, 7), + ) + u = a1.Union(a2) + assert.Equal(t, types.NewPos(2, 2, 2), u.Pos1) + assert.Equal(t, types.NewPos(5, 6, 7), u.Pos2) + + // non-intersecting area + a1 = types.NewArea( + types.NewPos(2, 2, 2), + types.NewPos(10, 10, 10), + ) + a2 = types.NewArea( + types.NewPos(11, 11, 11), + types.NewPos(13, 13, 13), + ) + u = a1.Union(a2) + assert.Nil(t, u) + + // 1-node intersects + a1 = types.NewArea( + types.NewPos(2, 2, 2), + types.NewPos(2, 2, 2), + ) + a2 = types.NewArea( + types.NewPos(2, 2, 2), + types.NewPos(2, 2, 2), + ) + u = a1.Union(a2) + assert.Equal(t, types.NewPos(2, 2, 2), u.Pos1) + assert.Equal(t, types.NewPos(2, 2, 2), u.Pos2) + assert.Equal(t, 1, u.Volume()) + assert.Equal(t, types.NewPos(1, 1, 1), u.Size()) +}