Hello, Alex is correct in that the intersection operation you are attempting to perform will only work in 2D. When you constructed bsp1 and bsp2 from the faces, what you ended up with was 2 half spaces of infinite size.
List<ConvexPolygon3D> list1 = new ArrayList<>(); list1.add(face1); RegionBSPTree3D bsp1 = RegionBSPTree3D.from(list1); // this is an infinite half space List<ConvexPolygon3D> list2 = new ArrayList<>(); list2.add(face2); RegionBSPTree3D bsp2 = RegionBSPTree3D.from(list2); // this is also an infinite half-space and is actually identical to the first one (The reason for this has to do with the way BSP trees represent regions. I suggest taking a look at the BSP tree tutorial on the commons-geometry site [1].) The intersection of those two infinite half-spaces is itself an infinite half-space. Regions of infinite size do not have a defined centroid, which is why the centroid in your example is null. In order to compute the intersection of the two polygons in your example, we have to use 2D space. We can either do the entire thing in 2D (as Alex demonstrated), or we can start in 3D and pop down to 2D when needed. This is the approach that I will show here. We'll start with the same 3D convex polygons that you had: List<Vector3D> pts1 = Arrays.asList( Vector3D.of(0, 10, 0), Vector3D.of(30, 10, 0), Vector3D.of(30, 20, 0), Vector3D.of(0, 20, 0)); ConvexPolygon3D face1 = Planes.convexPolygonFromVertices(pts1, precision); List<Vector3D> pts2 = Arrays.asList( Vector3D.of(10, 0, 0), Vector3D.of(20, 0, 0), Vector3D.of(20, 30, 0), Vector3D.of(10, 30, 0)); ConvexPolygon3D face2 = Planes.convexPolygonFromVertices(pts2, precision); Now, in order to perform the 2D intersection, we will first access the 2D geometries that are embedded in the 3D planes of the ConvexPolygon3D instances. You can picture a ConvexPolygon3D (and any other PlaneSubset subclass) as a 2D sticker stuck to a pane of glass (the infinite 3D plane). In the lines below, we are extracting the 2D "sticker" in order to work with it directly. ConvexArea area1 = face1.getEmbedded().getSubspaceRegion(); ConvexArea area2 = face2.getEmbedded().getSubspaceRegion(); We can now compute the intersection in 2D: RegionBSPTree2D areaBsp = RegionBSPTree2D.empty(); areaBsp.intersection(area1.toTree(), area2.toTree()); This gives us a finite 2D region with the expected centroid: Vector2D centroid2d = areaBsp.getCentroid(); System.out.println(centroid2d); // prints (15.000000000000002, -15.000000000000002) If we wish to take this 2D centroid back up to 3D, we can again use the subspace embedding information from the faces. In this case, we only need to use one of the faces: Vector3D centroid3d = face1.getEmbedded().toSpace(centroid2d); System.out.println(centroid3d); // prints (15.000000000000002, 15.000000000000002, 0.0) I hope this helps. Thank you for your interest in this project and feel free to reach out if you have any more questions. Regards, Matt J [1] https://commons.apache.org/proper/commons-geometry/tutorials/bsp-tree.html On Fri, Sep 16, 2022 at 6:10 AM Alex Herbert <alex.d.herb...@gmail.com> wrote: > > This may be related to the fact that you are using the 3D API with 2D > areas. Since the shapes have no volume the intersection may not be defined. > > This does work as expected in 2D: > > Precision.DoubleEquivalence precision = > Precision.doubleEquivalenceOfEpsilon(1e-6); > > List<Vector2D> pts1 = new ArrayList<>(); > pts1.add(Vector2D.of(0, 10)); > pts1.add(Vector2D.of(30, 10)); > pts1.add(Vector2D.of(30, 20)); > pts1.add(Vector2D.of(0, 20)); > ConvexArea face1 = ConvexArea.convexPolygonFromVertices(pts1, > precision); > > List<Vector2D> pts2 = new ArrayList<>(); > pts2.add(Vector2D.of(10, 0)); > pts2.add(Vector2D.of(20, 0)); > pts2.add(Vector2D.of(20, 30)); > pts2.add(Vector2D.of(10, 30)); > ConvexArea face2 = ConvexArea.convexPolygonFromVertices(pts2, > precision); > > RegionBSPTree2D bsp1 = RegionBSPTree2D.from(face1.getBoundaries()); > > RegionBSPTree2D bsp2 = RegionBSPTree2D.from(face2.getBoundaries()); > > RegionBSPTree2D result = RegionBSPTree2D.empty(); > result.intersection(bsp1, bsp2); > > System.out.println("Hello, Geometry! Centroid: " + > result.getCentroid()); > > Result: > > Hello, Geometry! Centroid: (15.000000000000002, 15.000000000000002) > > There may be a setting for the 3D equivalent to allow intersections on the > plane to be returned. I could not find anything obvious in the API. > > Regards, > > Alex > > > > On Fri, 16 Sept 2022 at 10:03, Bai Song <baisongm...@163.com> wrote: > > > Hi, Geometry Team > > > > I'm learning this interesting project and facing some difficulties when i > > did a little experiment. > > > > I created two ConvexPolygon3D instances (2 white rectangles in below > > image) on the same plane, and try to get the overlaping area(blue part) by > > RegionBSPTree3D intersection operation. > > > > > > But i got null when getting the centroid of the intersection. It looks > > that this test of intersection failed. > > Could you tell me how can i fix this? > > > > Thanks for your contribution to this project! > > > > //---------my test codes---------- > > public class TestIntersection > > { > > public static void main(String args[]) > > { > > Precision.DoubleEquivalence precision = > > Precision.doubleEquivalenceOfEpsilon(1e-6); > > > > List<Vector3D> pts1 = new ArrayList<>(); > > pts1.add(Vector3D.of(0, 10, 0)); > > pts1.add(Vector3D.of(30, 10, 0)); > > pts1.add(Vector3D.of(30, 20, 0)); > > pts1.add(Vector3D.of(0, 20, 0)); > > ConvexPolygon3D face1=Planes.convexPolygonFromVertices(pts1, > > precision); > > > > List<Vector3D> pts2 = new ArrayList<>(); > > pts2.add(Vector3D.of(10, 0, 0)); > > pts2.add(Vector3D.of(20, 0, 0)); > > pts2.add(Vector3D.of(20, 30, 0)); > > pts2.add(Vector3D.of(10, 30, 0)); > > ConvexPolygon3D face2 = Planes.convexPolygonFromVertices(pts2, > > precision); > > > > List<ConvexPolygon3D> list1 = new ArrayList<>(); > > list1.add(face1); > > RegionBSPTree3D bsp1 = RegionBSPTree3D.from(list1); > > > > List<ConvexPolygon3D> list2 = new ArrayList<>(); > > list2.add(face2); > > RegionBSPTree3D bsp2 = RegionBSPTree3D.from(list2); > > > > RegionBSPTree3D result = RegionBSPTree3D.empty(); > > result.intersection(bsp1, bsp2); > > > > System.out.println("Hello, Geometry! Centroid: > > "+result.getCentroid()); //expect (15,15,0), but got null actually > > } > > } > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org