Estimate Principal Axis Within Radius
SUMMARY
Estimate Principal Axis Within Radius computes the dominant local direction of a point cloud neighborhood around one reference point.
It only looks at the points within neighborhood_radius meters of reference_point, then runs PCA on that local neighborhood to find the direction of maximum variance — e.g. the long axis of a rod-like or elongated local feature. Compare with estimate_principal_axes, which analyzes the whole point cloud's orientation at once rather than a local neighborhood around one point.
Use this Skill when you want to determine the local orientation of one feature — an edge, rod, or elongated part — rather than an object's overall global orientation.
The Skill
from telekinesis import vitreous
local_principal_axis = vitreous.estimate_principal_axis_within_radius(
point_cloud=point_cloud,
neighborhood_radius=0.25,
reference_point=[0.0, 0.0, -0.52],
)Data Transfer Notice
There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.
Example
Input Point Cloud
Estimated principal axis shown in red calculated for neighborhood of a reference point.
Parameters: reference_point = np.array([0., 0., -0.52], dtype=np.float32), neighborhood_radius = 0.25.
The Code
"""
Demonstrates estimating the principal component axis of a point cloud neighborhood.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def estimate_principal_axis_within_radius_example():
"""
Estimates the principal component axis of a point cloud neighborhood.
Uses PCA to find the dominant direction in a local neighborhood around a
reference point.
"""
# ===================== Load Data ==========================================
point_cloud_url = (
"https://assets.telekinesis.ai/examples/v1/point_clouds/mug_preprocessed.ply"
)
point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)
# ===================== Run Skill ==========================================
# `estimate_principal_axis_within_radius` returns a Vector3D datatype instance.
local_principal_axis = vitreous.estimate_principal_axis_within_radius(
point_cloud=point_cloud,
neighborhood_radius=0.25,
reference_point=[0.0, 0.0, -0.52],
)
# ===================== Log ================================================
logger.success("Estimated principal axis within radius")
logger.success(f"Results: {local_principal_axis}")
logger.info(f"Local principal axis data: {local_principal_axis.data}")
logger.info(f"Local principal axis shape: {local_principal_axis.shape}")
logger.info(f"Local principal axis dtype: {local_principal_axis.dtype}")
# ===================== Visualization (Optional) ===========================
rr.init("estimate_principal_axis_within_radius_example", spawn=True)
datatypes.visualize(point_cloud, entity_path="/1-point_cloud")
datatypes.visualize(local_principal_axis, entity_path="/2-local_principal_axis")
if __name__ == "__main__":
estimate_principal_axis_within_radius_example()Runnable examples are available in the Telekinesis examples repository.
Follow the README in that repository to set up the environment, run this specific example with:
cd telekinesis-examples
python examples/point_cloud/estimate_principal_axis_within_radius.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to analyze. Should have a locally dominant direction near reference_point (e.g. an elongated feature), otherwise the estimated axis is not meaningful |
neighborhood_radius | datatypes.Float | float | int | 1.0 | Radius, in meters, of the spherical neighborhood around reference_point to analyze |
reference_point | datatypes.Vector3D | np.ndarray | list[float] | [0.0, 0.0, 0.0] | The 3D center [x, y, z], in meters, of the neighborhood to analyze — only points within neighborhood_radius of this point contribute to the estimate |
Returns
| Type | Description |
|---|---|
datatypes.Vector3D | The normalized principal-axis direction [x, y, z] of the local neighborhood. Use .data for the raw (3,) array. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above), or (for a list reference_point) it contains a non-numeric element |
ValueError | reference_point does not have exactly 3 elements |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Vitreous service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
neighborhood_radius
- Controls: How far from
reference_pointa point can be and still be included in the local PCA. - Units: Meters
- Default:
1.0 - Increase → includes more points — a more global, averaged direction, but risks pulling in points from unrelated regions
- Decrease → uses fewer points — a more local direction, but noisier
- Typical range: 0.1–10.0 meters — 0.1–1.0 for local features, 1.0–5.0 for regional analysis, 5.0–10.0 for near-global
reference_point
- Controls: The 3D center of the neighborhood being analyzed.
- Units: Meters
- Default:
[0.0, 0.0, 0.0](the origin) - Typically set to a point of interest, such as the output of
calculate_point_cloud_centroid, or a manually chosen location on the feature you want to analyze - Must have exactly 3 elements, or a
ValueErroris raised
TIP
Set reference_point to the center of the feature you want to analyze (e.g. a cluster's centroid from calculate_point_cloud_centroid), then size neighborhood_radius to just cover that feature — too large a radius pulls in unrelated geometry, too small starves the PCA of points.
Where to Use the Skill
Common pipelines include:
- Edge and rod orientation – find the long axis of a handle, tube, or bar for insertion or alignment
- Fine manipulation – orient a gripper to a local feature rather than the whole object
- Per-cluster local analysis – after
cluster_point_cloud_using_dbscan, get the local axis of one cluster around its centroid - Dense-scene feature extraction – analyze one region of interest without being influenced by the rest of a cluttered scene
Alternative Skills
| Skill | vs. Estimate Principal Axis Within Radius |
|---|---|
| estimate_principal_axes | Estimates all three axes of the entire point cloud's orientation instead of one local direction. Use it when you need the whole object's global orientation. |
| calculate_oriented_bounding_box | Also returns orientation, but for the whole object and bundled with size/extent. Use it when you need dimensions as well as a direction. |
When Not to Use the Skill
Do not use Estimate Principal Axis Within Radius when:
- You need the whole object's orientation — use
estimate_principal_axesinstead - You also need size or extent information — use
calculate_oriented_bounding_boxinstead - The neighborhood is too sparse — not enough points fall within
neighborhood_radiusfor a reliable PCA result - You don't yet know where to center the analysis — run
estimate_principal_axes(orcalculate_point_cloud_centroid) first to find a reference point - The local region has no clear dominant direction — a roughly spherical or uniform local neighborhood won't yield a meaningful axis
WARNING
This Skill needs enough points inside neighborhood_radius to compute a reliable axis. If the neighborhood is too sparse, widen the radius, choose a denser region, or preprocess the point cloud (e.g. remove outliers) before estimating.

