ftk - Mathematical and Utility Functions

@author Fraser Callaghan

ngawari.ftk.getIDOfClosestFloat(iFloat, floatList)[source]
ngawari.ftk.getClosestFloat(iFloat, floatList)[source]
ngawari.ftk.getIDOfClosestPoint(point, points)[source]
ngawari.ftk.getClosestPoint(point, points)[source]
ngawari.ftk.distPointPoints(point, points)[source]
ngawari.ftk.squareDistPointPoints(point, points)[source]
ngawari.ftk.sortedIDsOfClosestPoints(point, points)[source]
ngawari.ftk.distTwoPoints(a, b)[source]
ngawari.ftk.getIDsOfClosestPoints(pointsA, pointsB)[source]
ngawari.ftk.getIDsOfFartherestPoints(pointsA, pointsB)[source]
ngawari.ftk.vectorMagnitudes(vecs)[source]
ngawari.ftk.normaliseArray(vectors)[source]

Normalise an array of vectors.

Parameters: vectors (array-like): Input array of vectors. Can be 1D or 2D.

Returns: numpy.ndarray: Array of normalised vectors.

ngawari.ftk.angleBetween2Vec(v1, v2, RETURN_DEGREES=False)[source]
Returns the angle in radians between vectors ‘v1’ and ‘v2’::

Can be lists of same size

Parameters:
  • v1

  • v2

  • RETURN_DEGREES

Returns:

angle in radians

ngawari.ftk.angleBetweenVecAndPlane(vector, planeNormal)[source]
ngawari.ftk.areVecsMatching(v1, v2, angleTol_rad, magTol)[source]
ngawari.ftk.linearFit(X, Y)[source]

Fit a linear model to the data.

Parameters: - X: Independent variable. - Y: Dependent variable.

Returns: slope, intercept, R, pValue, std: Parameters of the linear model.

ngawari.ftk.fitPlaneToPoints(pts)[source]

Fit a plane to a set of 3D points.

Parameters: - pts: A numpy array of shape (N, 3) representing the 3D points.

Returns: - planeABC: Coefficients of the plane equation [a, b, c, d].

ngawari.ftk.polyfit2d(x, y, z, order=3)[source]
ngawari.ftk.polyval2d(x, y, m)[source]
ngawari.ftk.projectPtsToPlane(pts, plane)[source]

projects the points so all lie on the plane :param pts: list/array of points Nx3 :param plane: equation of plane: either [a,b,c,d] or [norm, ptInPlane] :return: pts array all lying on plane

ngawari.ftk.project3DPointsToPlanarCoordinateSystem(pts, planeNorm=None)[source]
ngawari.ftk.project3DPointsToPlanarCoordinateSystem_OLD(pts, planeNorm=None)[source]
Will rotate pts to lie in given plane
  • shifts pts to be centered on origin

FIXME: If points are aligned with an axis (almost) then will fail.

  • raise LinAlgError

    Need to check for this, then simply rotate by different vector set.

source: http://mathforum.org/library/drmath/view/51727.html source: https://stackoverflow.com/questions/23472048/projecting-3d-points-to-2d-plane :param pts: :param planeNorm: :return:

ngawari.ftk.project3DPointsToPlanarCoordinateSystem2(pts, planeNorm=None, datumPt=None)[source]
ngawari.ftk.convert2DPointsTo3DCoordinateSystem(xy, e1, e2, origin)[source]
ngawari.ftk.fitCircle2D(pts, xGuess=0.0, yGuess=0.0, radiusGuess=1.0)[source]
ngawari.ftk.fitCircleRANSAC(x, y, tolerance, FRACTION_PTS_USE_FOR_CONVERGENCE, MAX_ITERATIONS, EXCLUDE_INNERS=False, DEBUG=False)[source]
Parameters:
  • x

  • y

  • tolerance

  • FRACTION_PTS_USE_FOR_CONVERGENCE

  • MAX_ITERATIONS

  • EXCLUDE_INNERS

  • DEBUG

Returns:

ngawari.ftk.fitCircleRANSAC3D_xyz(xyz, tolerance, FRACTION_PTS_USE_FOR_CONVERGENCE, MAX_ITERATIONS, EXCLUDE_INNERS=False, DEBUG=False)[source]
ngawari.ftk.fit_ellipse_2d(points2d)[source]

Fit an ellipse to 2D points. :param points2d: 2D points to fit ellipse to :return: ellipse parameters (a, b, c, d, e, f) where ax^2 + bxy + cy^2 + dx + ey + f = 0

ngawari.ftk.fit_ellipse_3d(points)[source]

Fit an ellipse to 3D points that approximately lie on a plane.

Parameters:

points ((N,3) array_like) – Input 3D coordinates.

Returns:

result

{

‘center_3d’ : np.ndarray (3,) - ellipse center in 3D ‘normal’ : np.ndarray (3,) - unit normal of plane ‘axes’ : np.ndarray (2,) - [major, minor] axes lengths ‘angle’ : float - rotation angle (radians) within plane ‘u’ : np.ndarray (3,) - in-plane x-axis ‘v’ : np.ndarray (3,) - in-plane y-axis ‘points_3d’ : (N,3) np.ndarray - fitted ellipse points in 3D

}

Return type:

dict

ngawari.ftk.buildCircle3D(X, N, R, nPts=50)[source]
Parameters:
  • X – centre of circle

  • N – normal of circle

  • R – radius of circle

  • nPts – number of points to place around circumference [50]

Returns:

xyz of points on circumference of circle

ngawari.ftk.fitPlaneToPointCloud_RANSAC(pts, planeSearchDist_abs, planeFractionToInclude, max_iterations=1000, VERBOSE=False)[source]
Fits a plane to a 3D point cloud using RANSAC.

Choose random point Take next two closest points - calc plane Test number of points within planeSearchDist_abs

If > planeFractionToInclude

test RMSE vs best

Parameters: - pts: A numpy array of shape (N, 3) representing the 3D point cloud. - planeSearchDist_abs: The absolute distance to search for points for plane RMSE calc. - planePercentageToInclude: The fraction of points required to be part of plane. - max_iterations: The maximum number of iterations for the RANSAC algorithm (default=1000). - random_state: Random state for reproducibility (default=None).

Returns: - plane_normal: A numpy array representing the normal vector of the fitted plane. - plane_center: A numpy array representing a point on the fitted plane.

ngawari.ftk.linerFit_RANSAC(x, y, min_inliers_ratio, n_trials=100, sample_size=None, threshold=None)[source]

linear fit using RANSAC to handle outliers .

Parameters:
  • x (1D numpy arrays)

  • y (1D numpy arrays)

  • min_inliers_ratio (float (required)) – Fraction of total points that must agree with a candidate line for it to be considered a good fit (e.g. 0.65 if up to 35% may be outliers).

  • n_trials (int) – Number of random trials. Default 100.

  • sample_size (int or None) – Number of points to sample per trial. Defaults to 10% of n (min 2).

  • threshold (float or None) – Max residual to count as an inlier. If None, estimated automatically from median abs deviation

Returns:

  • best_slope, best_intercept (float)

  • best_inliers (boolean array marking inlier points)

ngawari.ftk.deg2rad(deg)[source]
ngawari.ftk.rad2deg(rad)[source]
ngawari.ftk.rotateArray(velArray, rotationMatrix)[source]
ngawari.ftk.rotationMatrixFromThreeAngles(xTheta, yTheta, zTheta)[source]
ngawari.ftk.getClosestInSortedList(listIn, ref, INCREASEING=True)[source]
ngawari.ftk.getIdOfClosestFloat(listIn, ref)[source]
ngawari.ftk.polar2Cart(r, theta)[source]
ngawari.ftk.polar2z(r, theta)[source]
ngawari.ftk.z2Polar(z)[source]
ngawari.ftk.cart2Polar(x, y)[source]
ngawari.ftk.unit_vector(vector)[source]

Returns the unit vector of the vector.

ngawari.ftk.vecFromPtToLine(pt, ptOnLine, lineNorm)[source]
ngawari.ftk.fcdot(u, v)[source]

dot product of two lists of vecs

ngawari.ftk.cosineDifferenceBetweenTwoMats(mA, mB)[source]
ngawari.ftk.getVectorComponentAlongRefVec(velVec, refVec)[source]

Returns vec parallel to refVec

ngawari.ftk.getVectorComponentAlongRefVec_Mag(velVec, refVec)[source]

Returns magnitude (signed) of vec parallel to refVec

ngawari.ftk.getVectorComponentNormalToRefVec(velVec, refVec)[source]

Returns vec component in plane normal to refVec

ngawari.ftk.closeCurve(xyz)[source]
ngawari.ftk.splinePoints(xyz, nSplinePts, periodic=0, RETURN_NUMPY=False, smooth=0, u=None, weights=None, derivitive=0)[source]

returns list, shape (3, n), unless ask for numpy then transpose

ngawari.ftk.splineFunction(x, y, kind)[source]
ngawari.ftk.splineXY(x, y, nPts, kind='linear', per=False)[source]

Input : x, y, numPts Output : X, Y

ngawari.ftk.splineCurve(x, y, nPts, interpolation_method='cubic')[source]

Spline is 2D (i.e x not always increasing)

Parameters:
  • x (np.array) – x array

  • y (np.array) – y array

  • interpolation_methods (str, optional) – of ‘slinear’, ‘quadratic’, ‘cubic’]. Defaults to ‘cubic’.

ngawari.ftk.getMaxsMinsInflections(X)[source]

Simple extrema finder :param X: 1D array :return: linst of maxima, list of minima, lint of inflections

ngawari.ftk.sigmoidFunction(value, center=0.0, gradient=1.0)[source]

calculate sigmoid function of input value (np array) center is what to adjust input by so zero centered gradient is used to adjust slope of sigmoid -

(adjusted) values above this number will have output > 0.72

ngawari.ftk.extractContinuousSegFromPeriodic(xx, IDstart, IDend, TIME=False)[source]

Take a sub section from an array, assuming periodic (to deal with subsection going beyond bounds)

ngawari.ftk.fitGaussianToData(xx, yy)[source]
ngawari.ftk.gaussianFunction(value, center=0.0, width=1.0, height=1.0)[source]

calculate gaussian function of input value (np array) center is what to adjust input by so zero centered width is standard dev of bell curve height is height of peak

ngawari.ftk.calculate_signed_area_2d(points_2d)[source]
ngawari.ftk.isClosedPolygonClockwise(xyzIn, refVec)[source]
ngawari.ftk.ensureClosedPolyIsClockwise(xzyIn, refVec)[source]
ngawari.ftk.setFirstPtOfPolygon(xyzIn, refVec)[source]

Reorder the points of a polygon so that the first point is closest to the refVec (e.g. ‘12 o’clock’ position).

This function assumes the polygon is planar and reorders the points so that the first point is the one closest to the end of a vector starting from the polygon’s center point and pointing in the direction of the reference vector.

Parameters: xyzIn (array-like): Input points of the polygon. refVec (array-like): Reference vector indicating the ‘12 o’clock’ direction.

Returns: numpy.ndarray: Reordered points of the polygon.

ngawari.ftk.reorderPointsStartClosestToX(pts, X)[source]
ngawari.ftk.reorderPointsStatingAti(pts, i)[source]
ngawari.ftk.sortPointsByClosest_RETURNIDs(xyz, refX0)[source]

Grab closest to refX0, grab next closest, keep going in that direction RETURN IDs

ngawari.ftk.sortPointsByClosest(xyz)[source]

Grab first, grab closest, keep going in that direction

ngawari.ftk.cumulativeDistanceAlongLine(xyzPts)[source]

Return array same len as input with sum of dists [0.0, dist-0to1, dist-0to1to2, …]

ngawari.ftk.getIdOfPointClosestToX(X, xyz)[source]
ngawari.ftk.getPolygonMeanRadius(xyzIn, EXCLUDE_CENTER=True)[source]
ngawari.ftk.getPolygonMeanDiameter(xyzIn)[source]
ngawari.ftk.getPolygonCenterPoint(xyzIn)[source]
ngawari.ftk.lineMagnitude(lineStartxyz, lineEndxyz)[source]
ngawari.ftk.distancePointToLineSegPerpendicular(lineStartxyz, lineEndxyz, ptxyz)[source]
ngawari.ftk.ndarrayToListOfTuple3(ndArrayIn)[source]
ngawari.ftk.diff(myList)[source]
ngawari.ftk.circleFit2DErr(allParams, xData, yData)[source]

Fit a circle to points

ngawari.ftk.distanceToPlane(p0, n, x)[source]
ngawari.ftk.residualPlane(parameters, X, Y, Z)[source]
ngawari.ftk.residualsCircle(parameters, sArr, rArr, point, X, Y, Z)[source]
ngawari.ftk.icp(sourcePts, targetPts, max_iterations=100, tolerance=1e-06)[source]

Iterative Closest Point (ICP) algorithm for point set registration.

Parameters: - X: A numpy array of shape (N, 3) representing the source set of 3D points. - Y: A numpy array of shape (M, 3) representing the target set of 3D points. - max_iterations: Maximum number of iterations for the algorithm (default=100). - tolerance: Convergence criterion based on the change in error (default=1e-6).

Returns: - R_best: A 3x3 numpy array representing the best rotation matrix. - t_best: A 1x3 numpy array representing the best translation vector.

ngawari.ftk.fitPlane3DOptimize(pts)[source]
ngawari.ftk.fitCircle3D(x, y, z, xm, ym, zm, rm)[source]

Fit a circle to 3D points.

Parameters: - x, y, z: Arrays of x, y, and z coordinates of the points. - xm, ym, zm: Coordinates of the center of the circle. - rm: Radius of the circle.

Returns: - centerPointArr: Coordinates of the center of the circle. - RiF: Radius of the circle. - normal: Normal vector of the plane containing the circle.

ngawari.ftk.lagBetweenTwoCurves(y1: array, y2: array, timeArray: array | None = None)[source]

Calculate the lag (delay) between two similar time series curves.

This function uses cross-correlation to determine the time delay between two signals.

Parameters: - y1 (np.array): First time series. - y2 (np.array): Second time series. - timeArray (np.array, optional): Array of time points corresponding to y1 and y2.

If None, a normalized time array from -0.5 to 0.5 is used. Default is None.

Returns: - float: The time delay between the two signals. A positive value indicates

that y2 lags behind y1, while a negative value indicates that y1 lags behind y2.

Note: - The two input arrays (y1 and y2) must have the same length. - If timeArray is provided, it must have the same length as y1 and y2.

ngawari.ftk.calculatePlaneThreePoints(p0, p1, p2)[source]

Plane from three points (v0(p0 to p1) and v1(p0 to p2) -> cross == norm, p2 for D) Return [A,B,C,D]

ngawari.ftk.getPlaneConstantsFromPointAndVector(pt, vector)[source]
ngawari.ftk.calculateDerivativeOnLine_backwardDiff(pim1, pi, dt)[source]

Calculate the derivative of a line using backward difference.

ngawari.ftk.calculateSecondDerivativeOnLine(pim1, pi, pip1, dt)[source]
ngawari.ftk.calculateCurvature3Pts(pim1, pi, pip1, dx)[source]
ngawari.ftk.calculateCurvature_D(gf: array, ggf: array)[source]
ngawari.ftk.setVectorDirection(vecIn, oo, pointMorePositive)[source]

Will ensure vector at point oo is pointing towards ‘pointMorePositive’ else flip

ngawari.ftk.buildRotationMatrix(vec, theta_rad)[source]
ngawari.ftk.adjustPointsCenterOfMassToOrigin(pts)[source]
ngawari.ftk.areVecsConsistent(vecA, vecB)[source]
ngawari.ftk.setVecAConsitentWithVecB(vecA, vecB)[source]

Make vec dir consistant with poly order

ngawari.ftk.buildConvexHUll3D(xyz, nPts=25, planeABCD=None, TO_SPLINE=True)[source]
ngawari.ftk.orderPointsConvexHull_IDs(xyz)[source]
ngawari.ftk.orderPointsConvexHull(xyz)[source]
ngawari.ftk.groupContinuousLinesByTol(ptsIn, tol)[source]

pts is N x 3 array of pts forming continuous lines (at least one) separated by gaps of ‘tol’ Returns list of pts separated

ngawari.ftk.buildContinuousLineByClosestPt(ptsIn)[source]

pts is N x 3 array of pts returns points ordered by proximity

ngawari.ftk.accumulatedAverage(arrayIn)[source]

Calc array that is average from start to i of input

ngawari.ftk.interpolateNANsFromSurroundingValues_cubic(nparray)[source]
ngawari.ftk.doesLineSegPierceTriangle(lineP0, lineP1, triP0, triP1, triP2)[source]
ngawari.ftk.doesLinePierceTriangle(lineP0, lineP1, triP0, triP1, triP2)[source]
ngawari.ftk.pluckerSideOperator(line0, line1)[source]
ngawari.ftk.pluckerLine(line)[source]
ngawari.ftk.doesVectorPierceAnyTriangle(vS, vE, triPolyData)[source]
ngawari.ftk.calculateBSA(height_cm, weight_kg, METHOD='DuBois')[source]
ngawari.ftk.interpolateNANsFromSurroundingValues_linear(array)[source]

This is linear temporal interpolation

ngawari.ftk.convexHull(P)[source]

Calculate the convex hull of a set of points.

Vector Operations

ngawari.ftk.normaliseArray(vectors)[source]

Normalise an array of vectors.

Parameters: vectors (array-like): Input array of vectors. Can be 1D or 2D.

Returns: numpy.ndarray: Array of normalised vectors.

ngawari.ftk.fcdot(u, v)[source]

dot product of two lists of vecs

ngawari.ftk.angleBetween2Vec(v1, v2, RETURN_DEGREES=False)[source]
Returns the angle in radians between vectors ‘v1’ and ‘v2’::

Can be lists of same size

Parameters:
  • v1

  • v2

  • RETURN_DEGREES

Returns:

angle in radians

ngawari.ftk.distTwoPoints(a, b)[source]

Matrix Operations

ngawari.ftk.rotationMatrixFromThreeAngles(xTheta, yTheta, zTheta)[source]
ngawari.ftk.buildRotationMatrix(vec, theta_rad)[source]
ngawari.ftk.rotateArray(velArray, rotationMatrix)[source]

Geometric Calculations

ngawari.ftk.fitPlaneToPoints(pts)[source]

Fit a plane to a set of 3D points.

Parameters: - pts: A numpy array of shape (N, 3) representing the 3D points.

Returns: - planeABC: Coefficients of the plane equation [a, b, c, d].

ngawari.ftk.fitPlaneToPointCloud_RANSAC(pts, planeSearchDist_abs, planeFractionToInclude, max_iterations=1000, VERBOSE=False)[source]
Fits a plane to a 3D point cloud using RANSAC.

Choose random point Take next two closest points - calc plane Test number of points within planeSearchDist_abs

If > planeFractionToInclude

test RMSE vs best

Parameters: - pts: A numpy array of shape (N, 3) representing the 3D point cloud. - planeSearchDist_abs: The absolute distance to search for points for plane RMSE calc. - planePercentageToInclude: The fraction of points required to be part of plane. - max_iterations: The maximum number of iterations for the RANSAC algorithm (default=1000). - random_state: Random state for reproducibility (default=None).

Returns: - plane_normal: A numpy array representing the normal vector of the fitted plane. - plane_center: A numpy array representing a point on the fitted plane.

ngawari.ftk.buildCircle3D(X, N, R, nPts=50)[source]
Parameters:
  • X – centre of circle

  • N – normal of circle

  • R – radius of circle

  • nPts – number of points to place around circumference [50]

Returns:

xyz of points on circumference of circle

ngawari.ftk.isClosedPolygonClockwise(xyzIn, refVec)[source]

Point and Line Utilities

ngawari.ftk.getIdOfPointClosestToX(X, xyz)[source]
ngawari.ftk.distPointPoints(point, points)[source]
ngawari.ftk.cumulativeDistanceAlongLine(xyzPts)[source]

Return array same len as input with sum of dists [0.0, dist-0to1, dist-0to1to2, …]

Mathematical Transformations

ngawari.ftk.rad2deg(rad)[source]
ngawari.ftk.deg2rad(deg)[source]
ngawari.ftk.setVecAConsitentWithVecB(vecA, vecB)[source]

Make vec dir consistant with poly order