12.1.10.7.3. Fit geometric element#

Fit geometric elements to pointClouds.

The circle has a radius 3.0 and is centered at (-5.516839607366819e-08, -8.886476621228212e-08)
The circle has a radius 3.000000238418579 and a angle of 44.999996150902604 and is centered at (-4.941995257468079e-08, 9.909079068393112e-08, 1.000000238418579)
The sphere has a radius 3.000039577484131 and is centered at (-5.266622611088678e-05, -4.388852175907232e-05, 3.5110817407257855e-05)
The cylinder has a radius 2.9833812713623047 and its axis is at (1.5903126001358032, -0.00011482834815979004, 0.01689159870147705) with the direction (-0.9999804496765137, 0.00580567866563797, 0.002306451788172126)
The line is at (-6.0, -6.0, 1.0) with the direction (-0.7071068286895752, -0.7071068286895752, 0.0)
The plane's direction is (1.4901089571139892e-06, 0.7071093916893005, -0.7071042060852051) with the constant 0.707102358341217

import numpy as np
import math as mathe
from itom import pointCloud
from itom import dataObject
from itom import algorithms
from itom import plot

geometryList = [
    "circle2D",
    "circle3D",
    "sphere",
    "cylinder",
    "line",
    "plane",
]
cloud = pointCloud()

for fitGeometry in geometryList:
    if fitGeometry == "line":
        X = np.arange(-3.1, 3.1, 0.1) * 3
        Y = np.arange(-3.1, 3.1, 0.1) * 3
        Z = np.ones(X.shape, X.dtype)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )
        # pclNorm = pointCloud()
        # filter("pclEstimateNormals", cloud, pclNorm)
        # [cPt, cAxis, cInl] = filter("pclFitLine", pclNorm, optimizeParameters=0)

        [cPt, cAxis, cInl] = algorithms.pclFitLine(cloud, optimizeParameters=0)
        print(
            "The line is at ({}, {}, {}) with the direction ({}, {}, {})".format(
                cPt[0], cPt[1], cPt[2], cAxis[0], cAxis[1], cAxis[2]
            )
        )

    elif fitGeometry == "plane":
        [X, Y] = np.meshgrid(np.arange(-2.0, 2.0, 0.1), np.arange(-2.0, 2.0, 0.1))
        Z = np.ones(X.shape, X.dtype) + Y * np.sin(45 * np.pi / 180)
        Y *= np.cos(45 * np.pi / 180)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

        [cVec, cPt, cInl] = algorithms.pclFitPlane(cloud, 1, optimizeParameters=0)

        print(
            f"The plane's direction is ({cVec[0]}, {cVec[1]}, {cVec[2]}) with the constant {cPt}"
        )

    elif fitGeometry == "circle2D":
        X = np.cos(np.arange(-3.1, 3.1, 0.1)) * 3
        Y = np.sin(np.arange(-3.1, 3.1, 0.1)) * 3
        Z = np.ones(X.shape, X.dtype)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

        [cPt, cRad, cInl] = algorithms.pclFitCircle2D(
            cloud, [1, 6], optimizeParameters=0
        )

        print(f"The circle has a radius {cRad} and is centered at ({cPt[0]}, {cPt[1]})")

    elif fitGeometry == "circle3D":
        X = np.cos(np.arange(-3.1, 3.1, 0.1)) * 3
        Y = np.sin(np.arange(-3.1, 3.1, 0.1)) * 3
        Z = np.ones(X.shape, X.dtype) + Y * np.sin(45 * np.pi / 180)
        Y *= np.cos(45 * np.pi / 180)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

        [cPt, cNormal, cRad, cInl] = algorithms.pclFitCircle3D(
            cloud, [1, 6], optimizeParameters=0
        )

        angle = (
            mathe.acos(
                cNormal[2]
                / (
                    cNormal[0] * cNormal[0]
                    + cNormal[1] * cNormal[1]
                    + cNormal[2] * cNormal[2]
                )
            )
            * 180
            / np.pi
        )

        angle = np.mod(angle, 90)

        print(
            "The circle has a radius {} and a angle of {} and is centered at ({}, {}, {})".format(
                cRad, angle, cPt[0], cPt[1], cPt[2]
            )
        )

    elif fitGeometry == "sphere":
        [X, Y] = np.meshgrid(np.arange(-2.0, 2.0, 0.1), np.arange(-2.0, 2.0, 0.1))
        Z = np.sqrt(9 - Y * Y - X * X)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

        [cPt, cRad, cInl] = algorithms.pclFitSphere(cloud, [1, 6], optimizeParameters=0)
        print(
            f"The sphere has a radius {cRad} and is centered at ({cPt[0]}, {cPt[1]}, {cPt[2]})"
        )
    elif fitGeometry == "cylinder":
        [X, Y] = np.meshgrid(np.arange(-2.0, 2.0, 0.1), np.arange(-2.0, 2.0, 0.1))
        Z = np.sqrt(9 - Y * Y)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

        # For cylinder fits we need normals defined
        pclNorm = pointCloud()
        algorithms.pclEstimateNormals(cloud, pclNorm)

        [cPt, cAxis, cRad, cInl] = algorithms.pclFitCylinder(
            pclNorm, [1, 6], optimizeParameters=0
        )
        print(
            "The cylinder has a radius {} and its axis is at ({}, {}, {}) with the direction ({}, {}, {})".format(
                cRad, cPt[0], cPt[1], cPt[2], cAxis[0], cAxis[1], cAxis[2]
            )
        )
    elif fitGeometry == "cone":
        # Not defined yet
        [X, Y] = np.meshgrid(np.arange(-2.0, 2.0, 0.1), np.arange(-2.0, 2.0, 0.1))
        Z = np.sqrt(Y * Y + X * X)
        cloud = pointCloud.fromXYZ(
            dataObject(X.astype("float32")),
            dataObject(Y.astype("float32")),
            dataObject(Z.astype("float32")),
        )

    plot(cloud)

Total running time of the script: (0 minutes 0.339 seconds)