Skip to main content
Question

How to compare pointcloud (distance) against a tilted surface

  • September 25, 2018
  • 3 replies
  • 75 views

romanhassas
Forum|alt.badge.img

I have a pointcloud of a rock slope that i would like to compare to a theoretic surface model (tilted surface). The next step would be to sort the point clouds into different colors depending on the distance to the surface. Anyone who has an idea which transformers to use?

This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

3 replies

daveatsafe
Safer
Forum|alt.badge.img+19
  • Safer
  • 1637 replies
  • September 25, 2018

Hi @info1,

If the theoretical surface is a simple plane, the simplest method would be to rotate the point cloud into the plane of that surface, then filter on the new elevation.

You can get the surface normal using the PlanarityFilter transformer, with Expose Surface Normal set to Yes.

The following Python can be used in a PythonCaller to calculate the parameters for a 3D rotation of the surface to horizontal:

import fmeobjectsimport mathdef calcRotation(feature):   normalX = feature.getAttribute('_surfaceNormalX')   normalY = feature.getAttribute('_surfaceNormalY')   normalZ = feature.getAttribute('_surfaceNormalZ')   vector = [normalX,normalY,normalZ]   length = math.sqrt(normalX**2 + normalY**2 + normalZ**2)   vertical = [0,0,length]   cross =  [vertical[1]*vector[2] - vertical[2]*vector[1],vertical[2]*vector[0] - vertical[0]*vector[2],vertical[0]*vector[1] - vertical[1]*vector[0]]   dot = vertical[0]*vector[0] + vertical[1]*vector[1] + vertical[2]*vector[2]   cos = dot/(length**2)   # in some edge cases, a slightly out of bounds cos may be created   if cos > 1.0:       cos = 1.0   if cos < -1.0:       cos = -1.0   rotation = math.acos(cos)*180/math.pi   feature.setAttribute('_vector_x',cross[0])   feature.setAttribute('_vector_y',cross[1])   feature.setAttribute('_vector_z',cross[2])   feature.setAttribute('_rotation',-rotation)   if rotation == 180 and cross == [0,0,0]:       feature.setAttribute('_length',-length)   else:       feature.setAttribute('_length',length)

Transfer the parameters to the point cloud, then use a 3DRotator to rotate the point cloud into alignment with the surface.

0684Q00000ArKiXQAV.png

Once the point cloud is rotated, you can use the PointCloudExpressionCalculator to copy the z component to a new proximity component.

To reset the point cloud to the original orientation, use another 3DRotator, with the same parameters, but with a negative rotation.

You can use the new proximity component to filter your points.

0684Q00000ArL5PQAV.png

I am attaching a workspace to illustrate the process:

pointcloudproximity.fmw


romanhassas
Forum|alt.badge.img
  • Author
  • 3 replies
  • September 26, 2018

Thanks for the answer @DaveAtSafe , my surface is not a simple plane. I was thinking of offsetting the surface, create a solid of the two surfaces and clip the points inside that solid, but could not manage to get it Work. Is that a possible solution?


daveatsafe
Safer
Forum|alt.badge.img+19
  • Safer
  • 1637 replies
  • September 26, 2018

Hi @info1,

You can use an Extruder to extrude the surface into a solid, then use that solid to clip the point cloud. The Extruder has the option to set the Extrusion vector, if you don't want to go straight up or down.