Hi,
Alex, thanks for your reply, saved me a lot of time! Matt, thanks for your detailed demo of 3D pop down to 2D, this helps me a lot! I'll do more trial in this way. I'm working on a wood working design and manufacturing software based on Trimble Sketchup. What i'm planning currently, is trying to move some board connecting detection from Sketchup plugin side ( based on some Sketchup 3D api in ruby ) to server side (in java, of course). Commons Geometry is the best 3D lib i can find in java world. Thanks again for your work! Regards, Bai Song At 2022-09-17 10:58:33, "Matt Juntunen" <matt.a.juntu...@gmail.com> wrote: >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