8

First off, I apologize if there is a solution for this somewhere, but I've done a great deal of digging through Three.js and A-Frame docs as well as Stack Overflow and haven't found what I'm looking for.

What I want to do is create a best-fit A-Frame plane from a set of Vector3s that I already know are coplanar. This can be easily done if the angle of the plane is a multiple of 90, but anything else and the .setFromPoints() algorithm for Box3s doesn't work the way I need it to.

The conversion from Three.js to A-Frame I can most likely handle myself, but if anyone wants to tackle that they're more than welcome to. I just need to create a rectangular plane that actually makes sense.

Basically, I want to create an algorithm that does this:

Create the bolded plane, rather than the lighter box/plane with too much wasted space.

Drawing Explanation

I don't want to create custom geometry that perfectly fits the points, which I've already done. I actually do just want an A-Frame plane with nothing but height, width, position, and rotation attributes. I understand this is less precise, but it's far more ideal for what I'm working on.

Roberto
  • 83
  • 5
  • @Soronbe Good performance is obviously preferred, but not required. Just trying to get things to work. And the amounts of vertices in any given set is usually around 10-15, but the most is 405. – Roberto Nov 09 '17 at 00:55

3 Answers3

2

OK, maybe my previous answer is to difficult to implement. Here is another idea: calculate the convex hull of your points (https://en.wikipedia.org/wiki/Graham_scan provides a simple and efficient algorithm with pseudo code). the inner points are not relevant. The optimum rectangle must coincide with at least one of the sides of the convex hull. With all angles of the sides of the convex hull calculate the dimensions of the rectangle with that angle. Then take the minimum.

Gerhard
  • 1,342
  • 2
  • 12
  • 23
1

First find the best line passing through the points. This is called "line fit", like here: http://stackoverflow.com/questions/2352256/fit-a-3d-line-to-3d-point-data-in-java , it should be easy to do this in two dimensions instead of three. See also here: https://en.wikipedia.org/wiki/Deming_regression The line gives you the angle, the minmax of the perpendicular distance of the points is the height of the rectangle, the minmax of the positions of the perpendicular foot points to the line makes the width of the rectangle. Or you rotate all points by the negativ angle of the line and simply calculate the minmax values of the x and y components of the points for the width and height of the rectangle.

Gerhard
  • 1,342
  • 2
  • 12
  • 23
0

For someone searching about calculating best fit rectangle for co-planar points in threejs, here is a simple solution that's fairly quick to implement:

  • Pick any 3 co-planar points on the plane A, B, C and calculate the planeNormal.

Then planeNormal = crossVectors(A-B, B-C);. Or if you have faces, take the average normal of all the faces.

  • Rotate all the points so that plane normal is Vector3(0,0,1)

For all points: point.applyMatrix4(new Matrix4().makeRotationFromQuaternion(new Quaternion().setFromUnitVectors(new Vector3(0,0,1), planeNormal).invert()))

  • Compute the bounding box size of the transformed points

size = new BoundingBox().setFromPoints(points).getSize(new Vector3());

This will give the rectangle width and height in x and y components. z should be 0 if all the points are co-planar.

Now we have the rectangle normal, width and height which is enough to create a plane geometry.

Palash Bansal
  • 708
  • 4
  • 9