pointcloud
stableA 3D point cloud class for managing collections of coloured XYZ points with operations for nearest-neighbour search, bounding box, centroid, transforms, subsampling, and binary serialisation.
use plugin pointcloud Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.
Functions (15)
- PointCloud.new Create an empty point cloud
- add_point Add an XYZ + RGB point
- remove_point Remove a point by index
- count Return number of points
- get_point Get a point by index
- clear Remove all points
- nearest_neighbor Find closest point to a query position
- bounding_box Compute axis-aligned bounding box
- centroid Compute mean position of all points
- translate Translate all points by an offset
- scale Scale all points by a factor
- subsample Create a new cloud keeping every Nth point
- rotate_y Rotate all points around the Y axis
- to_bytes Serialise points to packed binary bytes
- PointCloud.merge Merge two clouds into a new cloud
From import to result
- 01Import only what you use
- 02Copy the smallest example
- 03Run it with the Zolo CLI
Create an empty point cloud
Creates a new empty point cloud. Points store XYZ position as floats and RGB colour as 0–255 integer bytes.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(0.0, 0.0, 0.0, 255, 0, 0)
cloud.add_point(1.0, 0.0, 0.0, 0, 255, 0)
print("Points: {cloud.count()}")Add an XYZ + RGB point
Appends a point at position (x, y, z) with colour (r, g, b) where colour components are integers 0–255.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.5, 2.3, 0.1, 128, 200, 255)
cloud.add_point(0.0, 1.0, 3.0, 255, 128, 0)Remove a point by index
Removes the point at zero-based index idx. Shifts all subsequent points down by one. Raises an error if idx is out of bounds.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(0.0, 0.0, 0.0, 255, 0, 0)
cloud.add_point(1.0, 0.0, 0.0, 0, 255, 0)
cloud.remove_point(0)
print("Remaining: {cloud.count()}")Return number of points
Returns the number of points currently stored in the cloud.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(0.0, 0.0, 0.0, 0, 0, 0)
print("Count: {cloud.count()}")Get a point by index
Returns the point at zero-based index idx as a table with x, y, z (float) and r, g, b (int) fields.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(3.14, 2.71, 1.0, 100, 150, 200)
let p = cloud.get_point(0)
print("x={p["x"]} y={p["y"]} z={p["z"]}")Remove all points
Removes all points from the cloud without deallocating the underlying storage.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.0, 2.0, 3.0, 0, 0, 0)
cloud.clear()
print("After clear: {cloud.count()}")Find closest point to a query position
Finds the point closest to query position (x, y, z) using brute-force Euclidean distance. Returns a table with index, x, y, z, and distance fields, or nil if the cloud is empty.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(0.0, 0.0, 0.0, 255, 0, 0)
cloud.add_point(5.0, 5.0, 5.0, 0, 0, 255)
let nn = cloud.nearest_neighbor(1.0, 1.0, 1.0)
print("Nearest index: {nn["index"]}, dist: {nn["distance"]}")Compute axis-aligned bounding box
Computes the axis-aligned bounding box of all points. Returns a table with min_x, min_y, min_z, max_x, max_y, max_z fields. Returns nil if the cloud is empty.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(-1.0, 0.0, 2.0, 0, 0, 0)
cloud.add_point(3.0, 4.0, -1.0, 0, 0, 0)
let bb = cloud.bounding_box()
print("Min: {bb["min_x"]},{bb["min_y"]},{bb["min_z"]}")
print("Max: {bb["max_x"]},{bb["max_y"]},{bb["max_z"]}")Compute mean position of all points
Computes the arithmetic mean position of all points. Returns a table with x, y, z float fields, or nil if the cloud is empty.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(0.0, 0.0, 0.0, 0, 0, 0)
cloud.add_point(2.0, 4.0, 6.0, 0, 0, 0)
let c = cloud.centroid()
print("Centroid: {c["x"]}, {c["y"]}, {c["z"]}")Translate all points by an offset
Shifts all points in the cloud by the vector (dx, dy, dz). Modifies the cloud in-place.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.0, 2.0, 3.0, 255, 0, 0)
cloud.translate(-1.0, -2.0, -3.0)
let p = cloud.get_point(0)
print("After translate: {p["x"]},{p["y"]},{p["z"]}")Scale all points by a factor
Multiplies the XYZ coordinates of every point by factor. Useful for unit conversion or normalisation. Modifies the cloud in-place.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.0, 2.0, 3.0, 0, 255, 0)
cloud.scale(0.001)
let p = cloud.get_point(0)
print("Scaled x: {p["x"]}")Create a new cloud keeping every Nth point
Returns a new cloud containing every Nth point (stride subsampling). Useful for reducing density before expensive operations. n must be at least 1.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
// add many points...
cloud.add_point(0.0, 0.0, 0.0, 0, 0, 0)
cloud.add_point(1.0, 0.0, 0.0, 0, 0, 0)
cloud.add_point(2.0, 0.0, 0.0, 0, 0, 0)
cloud.add_point(3.0, 0.0, 0.0, 0, 0, 0)
let sparse = cloud.subsample(2)
print("Sparse count: {sparse.count()}")Rotate all points around the Y axis
Rotates all points around the Y axis by angle_rad radians. Modifies the cloud in-place.
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.0, 0.0, 0.0, 255, 0, 0)
cloud.rotate_y(3.14159)
let p = cloud.get_point(0)
print("After 180 rotation: x={p["x"]}, z={p["z"]}")Serialise points to packed binary bytes
Serialises all points to a compact binary format: each point is 27 bytes (3 × 8-byte little-endian float64 for XYZ, 3 × 1-byte uint8 for RGB).
use plugin pointcloud::{PointCloud}
let cloud = PointCloud.new()
cloud.add_point(1.0, 2.0, 3.0, 100, 150, 200)
let bytes = cloud.to_bytes()
print("Binary size: {bytes.len} bytes")Merge two clouds into a new cloud
Static method. Combines two point clouds into a new cloud containing all points from both. Does not modify either input cloud.
use plugin pointcloud::{PointCloud}
let a = PointCloud.new()
a.add_point(0.0, 0.0, 0.0, 255, 0, 0)
let b = PointCloud.new()
b.add_point(1.0, 1.0, 1.0, 0, 0, 255)
let combined = PointCloud.merge(a, b)
print("Merged count: {combined.count()}")