gokg

package module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 6 Imported by: 0

README

GOKG

aka "Golang kjkrol Geometry"

GOKG is a Go toolkit focused on practical 2D computational geometry. It splits into two packages: geom supplies numeric vectors (Vec), axis-aligned bounding boxes (AABB), and vector math; plane wraps those primitives in boundary-aware Space2D implementations (Euclidean2D and Toroidal2D) that keep boxes canonical to a surface. plane.AABB caches size and fragments so translations, wraps, and clamps obey the space’s rules without duplicating bookkeeping. The library stays focused on mathematical geometry; rendering or UI concerns live in neighbouring packages.

Space2D boundary handling

  • Euclidean2D spaces clamp boxes to the viewport while keeping their size consistent, so expansions never bleed beyond the defined world.

  • Toroidal2D spaces automatically wrap boxes that cross an edge and split them into fragments that continue on the opposite side, making toroidal worlds easy to model. Conceptually, glue the top edge of the plane to the bottom edge, then the left edge to the right; this seam-stitching turns the rectangle into the torus shown in the animation below.

    Torus

  • The helper methods Translate and Expand renormalise boxes on every call, updating cached fragments and ensuring touch/collision queries remain accurate without extra bookkeeping.

Usage example

This snippet shifts a contiguous plane.AABB by (-1,-1) across a 10×10 toroidal Space2D, so the box wraps past the right and bottom edges and automatically splits into the fragments returned by Fragments(). The exact situation is illustrated by the plot below.

Wrapped AABB fragments

package main

import (
	"fmt"

	"github.com/kjkrol/gokg/pkg/geom"
	"github.com/kjkrol/gokg/pkg/plane"
)

// Demonstrates how shifting a contiguous aabb beyond the toroidal plane boundary
// causes it to fragment into multiple wrapped pieces and prints those fragments.
func main() {
        toroidal := plane.NewToroidal2D(10, 10)

        box := geom.NewAABBAt(geom.NewVec(0, 0), 2, 2)
        aabb := toroidal.WrapAABB(box)

        shift := geom.NewVec(-1, -1)
        toroidal.Translate(&aabb, shift)

	fragments := aabb.Fragments()
	if len(fragments) < 3 {
		fmt.Printf("Unexpected fragment count (%d)\n", len(fragments))
		return
	}

	fmt.Printf("New position: %s\n", aabb)
	if fragment, ok := fragments[plane.FRAG_RIGHT]; ok {
		fmt.Printf("- Fragment %d: %s\n", plane.FRAG_RIGHT, fragment)
	}
	if fragment, ok := fragments[plane.FRAG_BOTTOM]; ok {
		fmt.Printf("- Fragment %d: %s\n", plane.FRAG_BOTTOM, fragment)
	}
	if fragment, ok := fragments[plane.FRAG_BOTTOM_RIGHT]; ok {
		fmt.Printf("- Fragment %d: %s\n", plane.FRAG_BOTTOM_RIGHT, fragment)
	}
	// Output:
	// New position: {(9,9) (10,10)}
	// - Fragment 0: {(0,9) (1,10)}
	// - Fragment 1: {(9,0) (10,1)}
	// - Fragment 2: {(0,0) (1,1)}
}

For more scenarios, browse the example-based tests under pkg/plane and pkg/geom, which double as runnable documentation.

Projects using GOKG

  • gokqGOKQ is a quadtree utility library that relies on geom.Vec, geom.AABB, and plane.AABB operations.
  • gokxGOKX is a Go library that provides a lightweight experimental framework for 2D graphics applications.

*Contributor Recommendations

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Width of the physical simulation world.
	Width uint32
	// Height of the physical simulation world.
	Height uint32
	// Toroidal determines if the world wraps around its edges (true) or clamps them (false).
	Toroidal bool
	// BucketSize determines the resolution of a single cell in the spatial grid.
	BucketSize spatial.Resolution
	// BucketCapacity is the initial number of entities a single grid bucket can hold before allocating more memory.
	BucketCapacity int
	// OpsBufferSize is the size of the channel buffer used for queuing spatial index updates.
	OpsBufferSize int
}

Config defines the properties of the Space.

type Space

type Space struct {
	Config
	// contains filtered or unexported fields
}

Space represents the main physical domain of the simulation. It acts as a facade that synchronizes boundary-aware geometry (plane.Space2D) with a highly optimized spatial index (spatial.GridIndexManager), providing a single, safe entry point for entity manipulation and querying.

func NewSpace

func NewSpace(cfg Config) (*Space, error)

NewSpace constructs a new Space with the given Config. It automatically handles asymmetric world dimensions by fitting them into the nearest power-of-two spatial grid internally, keeping the API simple and hiding complex topology.

func (*Space) Expand

func (w *Space) Expand(id uid.UID64, aabb *plane.AABB[uint32], margin uint32)

Expand grows or shrinks the given AABB by the specified margin, and immediately queues an update to the spatial index.

func (*Space) ExpandOnly added in v1.2.11

func (w *Space) ExpandOnly(aabb *plane.AABB[uint32], margin uint32)

ExpandOnly geometrically expands the AABB without updating the spatial index. This is useful for creating temporary probe boxes for broad-phase queries.

func (*Space) Flush

func (w *Space) Flush(onDirty func(geom.AABB[uint32]))

Flush processes all pending queued operations (Insert, Remove, Translate, Expand) and applies them to the underlying bucket grid. The onDirty callback is invoked for every modified bucket area, which is useful for triggering visual redraws.

func (*Space) Insert

func (w *Space) Insert(id uid.UID64, aabb plane.AABB[uint32])

Insert adds a new entity to the space. It first normalizes the AABB according to the Space topology (e.g., wraps it if Toroidal) and then queues it for insertion into the spatial grid.

func (*Space) Query

func (w *Space) Query(aabb geom.AABB[uint32], fn func(id uid.UID64, frag plane.FragPosition)) int

Query searches the spatial grid for all entities intersecting the provided AABB. The collector function fn is called for every entity found, providing its ID and the exact fragment that was hit.

func (*Space) Remove

func (w *Space) Remove(id uid.UID64)

Remove queues the entity with the given ID for removal from the spatial grid.

func (*Space) Translate

func (w *Space) Translate(id uid.UID64, aabb *plane.AABB[uint32], delta geom.Vec[uint32])

Translate moves the given AABB by the specified delta, recalculates its fragments based on the boundary rules, and queues a spatial index update to reflect the new position.

Directories

Path Synopsis
Package geom provides generic 2D geometry primitives shared across the GOK modules.
Package geom provides generic 2D geometry primitives shared across the GOK modules.
Package plane defines 2D spaces (cartesian and torus) plus plane-aware boxes and metrics.
Package plane defines 2D spaces (cartesian and torus) plus plane-aware boxes and metrics.
Package spatial provides a discrete spatial index over a 2D power-of-two grid for storing and querying objects by integer coordinates, with support for range queries (AABB) and bulk operations.
Package spatial provides a discrete spatial index over a 2D power-of-two grid for storing and querying objects by integer coordinates, with support for range queries (AABB) and bulk operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL