changeset 8046:726b5622b633

RT-38582 [Transform] transform(Bounds) and inverseTransform(Bounds) produce incorrect results Reviewed by: kcr, flar
author Martin Sladecek <martin.sladecek@oracle.com>
date Fri, 12 Sep 2014 09:34:50 +0200
parents 522fe51196c8
children 7f169b1de6c6
files modules/graphics/src/main/java/com/sun/javafx/geometry/BoundsUtils.java modules/graphics/src/main/java/javafx/scene/Node.java modules/graphics/src/main/java/javafx/scene/transform/Transform.java modules/graphics/src/test/java/javafx/scene/transform/TransformOperationsTest.java
diffstat 4 files changed, 214 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/javafx/geometry/BoundsUtils.java	Fri Sep 12 09:34:50 2014 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.geometry;
+
+import javafx.geometry.BoundingBox;
+import javafx.geometry.Bounds;
+import javafx.geometry.Point2D;
+import javafx.geometry.Point3D;
+
+public final class BoundsUtils {
+    private BoundsUtils() {}
+
+    private static double min4(double v1, double v2, double v3, double v4) {
+        return Math.min(Math.min(v1, v2), Math.min(v3, v4));
+    }
+
+    private static double min8(double v1, double v2, double v3, double v4,
+                               double v5, double v6, double v7, double v8) {
+        return Math.min(min4(v1, v2, v3, v4), min4(v5, v6, v7, v8));
+    }
+
+    private static double max4(double v1, double v2, double v3, double v4) {
+        return Math.max(Math.max(v1, v2), Math.max(v3, v4));
+    }
+
+    private static double max8(double v1, double v2, double v3, double v4,
+                               double v5, double v6, double v7, double v8) {
+        return Math.max(max4(v1, v2, v3, v4), max4(v5, v6, v7, v8));
+    }
+
+
+    public static Bounds createBoundingBox(Point2D p1, Point2D p2, Point2D p3, Point2D p4,
+                                           Point2D p5, Point2D p6, Point2D p7, Point2D p8) {
+
+        if (p1 == null || p2 == null || p3 == null || p4 == null
+                || p5 == null || p6 == null || p7 == null || p8 == null) {
+            return null;
+        }
+
+        double minX = min8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
+                p5.getX(), p6.getX(), p7.getX(), p8.getX());
+        double maxX = max8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
+                p5.getX(), p6.getX(), p7.getX(), p8.getX());
+
+        double minY = min8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
+                p5.getY(), p6.getY(), p7.getY(), p8.getY());
+        double maxY = max8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
+                p5.getY(), p6.getY(), p7.getY(), p8.getY());
+
+        return new BoundingBox(minX, minY, maxX - minX, maxY - minY);
+    }
+
+    public static Bounds createBoundingBox(Point3D p1, Point3D p2, Point3D p3, Point3D p4,
+                                           Point3D p5, Point3D p6, Point3D p7, Point3D p8) {
+
+        if (p1 == null || p2 == null || p3 == null || p4 == null
+                || p5 == null || p6 == null || p7 == null || p8 == null) {
+            return null;
+        }
+
+        double minX = min8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
+                p5.getX(), p6.getX(), p7.getX(), p8.getX());
+        double maxX = max8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
+                p5.getX(), p6.getX(), p7.getX(), p8.getX());
+
+        double minY = min8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
+                p5.getY(), p6.getY(), p7.getY(), p8.getY());
+        double maxY = max8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
+                p5.getY(), p6.getY(), p7.getY(), p8.getY());
+
+        double minZ = min8(p1.getZ(), p2.getZ(), p3.getZ(), p4.getZ(),
+                p5.getZ(), p6.getZ(), p7.getZ(), p8.getZ());
+        double maxZ = max8(p1.getZ(), p2.getZ(), p3.getZ(), p4.getZ(),
+                p5.getZ(), p6.getZ(), p7.getZ(), p8.getZ());
+
+        return new BoundingBox(minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ);
+    }
+
+    public static Bounds createBoundingBox(Point2D p1, Point2D p2, Point2D p3, Point2D p4) {
+
+        if (p1 == null || p2 == null || p3 == null || p4 == null) {
+            return null;
+        }
+
+        double minX = min4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
+        double maxX = max4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
+        double minY = min4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
+        double maxY = max4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
+
+        return new BoundingBox(minX, minY, maxX - minX, maxY - minY);
+    }
+}
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Fri Sep 12 09:20:28 2014 +0200
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Fri Sep 12 09:34:50 2014 +0200
@@ -26,6 +26,7 @@
 package javafx.scene;
 
 
+import com.sun.javafx.geometry.BoundsUtils;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.beans.binding.BooleanExpression;
@@ -3628,51 +3629,6 @@
     @Deprecated
     protected abstract boolean impl_computeContains(double localX, double localY);
 
-    private double min4(double v1, double v2, double v3, double v4) {
-        return Math.min(Math.min(v1, v2), Math.min(v3, v4));
-    }
-
-    private double max4(double v1, double v2, double v3, double v4) {
-        return Math.max(Math.max(v1, v2), Math.max(v3, v4));
-    }
-
-    private double min8(double v1, double v2, double v3, double v4,
-            double v5, double v6, double v7, double v8) {
-        return Math.min(min4(v1, v2, v3, v4), min4(v5, v6, v7, v8));
-    }
-
-    private double max8(double v1, double v2, double v3, double v4,
-            double v5, double v6, double v7, double v8) {
-        return Math.max(max4(v1, v2, v3, v4), max4(v5, v6, v7, v8));
-    }
-
-    Bounds createBoundingBox(Point3D p1, Point3D p2, Point3D p3, Point3D p4,
-            Point3D p5, Point3D p6, Point3D p7, Point3D p8) {
-        double minX = min8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
-                p5.getX(), p6.getX(), p7.getX(), p8.getX());
-        double maxX = max8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
-                p5.getX(), p6.getX(), p7.getX(), p8.getX());
-        double minY = min8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
-                p5.getY(), p6.getY(), p7.getY(), p8.getY());
-        double maxY = max8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
-                p5.getY(), p6.getY(), p7.getY(), p8.getY());
-        double minZ = min8(p1.getZ(), p2.getZ(), p3.getZ(), p4.getZ(),
-                p5.getZ(), p6.getZ(), p7.getZ(), p8.getZ());
-        double maxZ = max8(p1.getZ(), p2.getZ(), p3.getZ(), p4.getZ(),
-                p5.getZ(), p6.getZ(), p7.getZ(), p8.getZ());
-
-        return new BoundingBox(minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ);
-    }
-
-    Bounds createBoundingBox(Point2D p1, Point2D p2, Point2D p3, Point2D p4) {
-        double minX = min4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        double maxX = max4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        double minY = min4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-        double maxY = max4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-
-        return new BoundingBox(minX, minY, maxX - minX, maxY - minY);
-    }
-
     /*
      *                   Bounds Invalidation And Notification
      *
@@ -4037,16 +3993,7 @@
         final Point2D p3 = screenToLocal(screenBounds.getMaxX(), screenBounds.getMinY());
         final Point2D p4 = screenToLocal(screenBounds.getMaxX(), screenBounds.getMaxY());
 
-        if (p1 == null || p2 == null || p3 == null || p4 == null) {
-            return null;
-        }
-
-        final double minX = min4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        final double maxX = max4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        final double minY = min4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-        final double maxY = max4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-
-        return new BoundingBox(minX, minY, 0.0, maxX - minX, maxY - minY, 0.0);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
     }
 
 
@@ -4130,16 +4077,7 @@
         final Point2D p3 = sceneToLocal(bounds.getMaxX(), bounds.getMinY(), true);
         final Point2D p4 = sceneToLocal(bounds.getMaxX(), bounds.getMaxY(), true);
 
-        if (p1 == null || p2 == null || p3 == null || p4 == null) {
-            return null;
-        }
-
-        final double minX = min4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        final double maxX = max4(p1.getX(), p2.getX(), p3.getX(), p4.getX());
-        final double minY = min4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-        final double maxY = max4(p1.getY(), p2.getY(), p3.getY(), p4.getY());
-
-        return new BoundingBox(minX, minY, 0.0, maxX - minX, maxY - minY, 0.0);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
     }
 
     /**
@@ -4252,7 +4190,7 @@
             Point2D p3 = sceneToLocal(sceneBounds.getMaxX(), sceneBounds.getMaxY());
             Point2D p4 = sceneToLocal(sceneBounds.getMinX(), sceneBounds.getMaxY());
 
-            return createBoundingBox(p1, p2, p3, p4);
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
         }
         try {
             Point3D p1 = sceneToLocal0(sceneBounds.getMinX(), sceneBounds.getMinY(), sceneBounds.getMinZ());
@@ -4263,7 +4201,7 @@
             Point3D p6 = sceneToLocal0(sceneBounds.getMaxX(), sceneBounds.getMaxY(), sceneBounds.getMaxZ());
             Point3D p7 = sceneToLocal0(sceneBounds.getMaxX(), sceneBounds.getMinY(), sceneBounds.getMinZ());
             Point3D p8 = sceneToLocal0(sceneBounds.getMaxX(), sceneBounds.getMinY(), sceneBounds.getMaxZ());
-            return createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
         } catch (NoninvertibleTransformException e) {
             return null;
         }
@@ -4347,21 +4285,7 @@
         final Point2D p7 = localToScreen(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMinZ());
         final Point2D p8 = localToScreen(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMaxZ());
 
-        if (p1 == null || p2 == null || p3 == null || p4 == null
-                || p5 == null || p6 == null || p7 == null || p8 == null) {
-            return null;
-        }
-
-        final double minX = min8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
-                p5.getX(), p6.getX(), p7.getX(), p8.getX());
-        final double maxX = max8(p1.getX(), p2.getX(), p3.getX(), p4.getX(),
-                p5.getX(), p6.getX(), p7.getX(), p8.getX());
-        final double minY = min8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
-                p5.getY(), p6.getY(), p7.getY(), p8.getY());
-        final double maxY = max8(p1.getY(), p2.getY(), p3.getY(), p4.getY(),
-                p5.getY(), p6.getY(), p7.getY(), p8.getY());
-
-        return new BoundingBox(minX, minY, maxX - minX, maxY - minY);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
     }
 
     /**
@@ -4533,7 +4457,7 @@
         Point3D p6 = localToScene(localBounds.getMaxX(), localBounds.getMaxY(), localBounds.getMaxZ(), true);
         Point3D p7 = localToScene(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMinZ(), true);
         Point3D p8 = localToScene(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMaxZ(), true);
-        return createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
     }
 
     /**
@@ -4555,7 +4479,7 @@
             Point2D p3 = localToScene(localBounds.getMaxX(), localBounds.getMaxY());
             Point2D p4 = localToScene(localBounds.getMinX(), localBounds.getMaxY());
 
-            return createBoundingBox(p1, p2, p3, p4);
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
         }
         Point3D p1 = localToScene(localBounds.getMinX(), localBounds.getMinY(), localBounds.getMinZ());
         Point3D p2 = localToScene(localBounds.getMinX(), localBounds.getMinY(), localBounds.getMaxZ());
@@ -4565,7 +4489,7 @@
         Point3D p6 = localToScene(localBounds.getMaxX(), localBounds.getMaxY(), localBounds.getMaxZ());
         Point3D p7 = localToScene(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMinZ());
         Point3D p8 = localToScene(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMaxZ());
-        return createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
 
     }
 
@@ -4633,7 +4557,7 @@
             Point2D p3 = parentToLocal(parentBounds.getMaxX(), parentBounds.getMaxY());
             Point2D p4 = parentToLocal(parentBounds.getMinX(), parentBounds.getMaxY());
 
-            return createBoundingBox(p1, p2, p3, p4);
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
         }
         Point3D p1 = parentToLocal(parentBounds.getMinX(), parentBounds.getMinY(), parentBounds.getMinZ());
         Point3D p2 = parentToLocal(parentBounds.getMinX(), parentBounds.getMinY(), parentBounds.getMaxZ());
@@ -4643,7 +4567,7 @@
         Point3D p6 = parentToLocal(parentBounds.getMaxX(), parentBounds.getMaxY(), parentBounds.getMaxZ());
         Point3D p7 = parentToLocal(parentBounds.getMaxX(), parentBounds.getMinY(), parentBounds.getMinZ());
         Point3D p8 = parentToLocal(parentBounds.getMaxX(), parentBounds.getMinY(), parentBounds.getMaxZ());
-        return createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
     }
 
     /**
@@ -4702,7 +4626,7 @@
             Point2D p3 = localToParent(localBounds.getMaxX(), localBounds.getMaxY());
             Point2D p4 = localToParent(localBounds.getMinX(), localBounds.getMaxY());
 
-            return createBoundingBox(p1, p2, p3, p4);
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
         }
         Point3D p1 = localToParent(localBounds.getMinX(), localBounds.getMinY(), localBounds.getMinZ());
         Point3D p2 = localToParent(localBounds.getMinX(), localBounds.getMinY(), localBounds.getMaxZ());
@@ -4712,7 +4636,7 @@
         Point3D p6 = localToParent(localBounds.getMaxX(), localBounds.getMaxY(), localBounds.getMaxZ());
         Point3D p7 = localToParent(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMinZ());
         Point3D p8 = localToParent(localBounds.getMaxX(), localBounds.getMinY(), localBounds.getMaxZ());
-        return createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
     }
 
     /**
--- a/modules/graphics/src/main/java/javafx/scene/transform/Transform.java	Fri Sep 12 09:20:28 2014 +0200
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Transform.java	Fri Sep 12 09:34:50 2014 +0200
@@ -26,6 +26,8 @@
 package javafx.scene.transform;
 
 import java.util.Iterator;
+
+import com.sun.javafx.geometry.BoundsUtils;
 import javafx.event.EventDispatchChain;
 
 import javafx.scene.Node;
@@ -1239,16 +1241,24 @@
      * @since JavaFX 8.0
      */
     public Bounds transform(Bounds bounds) {
-        final Point3D base = transform(
-                bounds.getMinX(),
-                bounds.getMinY(),
-                bounds.getMinZ());
-        final Point3D size = deltaTransform(
-                bounds.getWidth(),
-                bounds.getHeight(),
-                bounds.getDepth());
-        return new BoundingBox(base.getX(), base.getY(), base.getZ(),
-                size.getX(), size.getY(), size.getZ());
+        if (isType2D() && (bounds.getMinZ() == 0) && (bounds.getMaxZ() == 0)) {
+            Point2D p1 = transform(bounds.getMinX(), bounds.getMinY());
+            Point2D p2 = transform(bounds.getMaxX(), bounds.getMinY());
+            Point2D p3 = transform(bounds.getMaxX(), bounds.getMaxY());
+            Point2D p4 = transform(bounds.getMinX(), bounds.getMaxY());
+
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
+        }
+        Point3D p1 = transform(bounds.getMinX(), bounds.getMinY(), bounds.getMinZ());
+        Point3D p2 = transform(bounds.getMinX(), bounds.getMinY(), bounds.getMaxZ());
+        Point3D p3 = transform(bounds.getMinX(), bounds.getMaxY(), bounds.getMinZ());
+        Point3D p4 = transform(bounds.getMinX(), bounds.getMaxY(), bounds.getMaxZ());
+        Point3D p5 = transform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMinZ());
+        Point3D p6 = transform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMaxZ());
+        Point3D p7 = transform(bounds.getMaxX(), bounds.getMinY(), bounds.getMinZ());
+        Point3D p8 = transform(bounds.getMaxX(), bounds.getMinY(), bounds.getMaxZ());
+        
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
     }
 
     /**
@@ -1536,17 +1546,25 @@
      */
     public Bounds inverseTransform(Bounds bounds)
             throws NonInvertibleTransformException {
+        if (isType2D() && (bounds.getMinZ() == 0) && (bounds.getMaxZ() == 0)) {
+            Point2D p1 = inverseTransform(bounds.getMinX(), bounds.getMinY());
+            Point2D p2 = inverseTransform(bounds.getMaxX(), bounds.getMinY());
+            Point2D p3 = inverseTransform(bounds.getMaxX(), bounds.getMaxY());
+            Point2D p4 = inverseTransform(bounds.getMinX(), bounds.getMaxY());
 
-        Point3D base = inverseTransform(
-                bounds.getMinX(),
-                bounds.getMinY(),
-                bounds.getMinZ());
-        Point3D size = inverseDeltaTransform(
-                bounds.getWidth(),
-                bounds.getHeight(),
-                bounds.getDepth());
-        return new BoundingBox(base.getX(), base.getY(), base.getZ(),
-                size.getX(), size.getY(), size.getZ());
+            return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
+        }
+        Point3D p1 = inverseTransform(bounds.getMinX(), bounds.getMinY(), bounds.getMinZ());
+        Point3D p2 = inverseTransform(bounds.getMinX(), bounds.getMinY(), bounds.getMaxZ());
+        Point3D p3 = inverseTransform(bounds.getMinX(), bounds.getMaxY(), bounds.getMinZ());
+        Point3D p4 = inverseTransform(bounds.getMinX(), bounds.getMaxY(), bounds.getMaxZ());
+        Point3D p5 = inverseTransform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMinZ());
+        Point3D p6 = inverseTransform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMaxZ());
+        Point3D p7 = inverseTransform(bounds.getMaxX(), bounds.getMinY(), bounds.getMinZ());
+        Point3D p8 = inverseTransform(bounds.getMaxX(), bounds.getMinY(), bounds.getMaxZ());
+
+        return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
+
     }
 
     /**
--- a/modules/graphics/src/test/java/javafx/scene/transform/TransformOperationsTest.java	Fri Sep 12 09:20:28 2014 +0200
+++ b/modules/graphics/src/test/java/javafx/scene/transform/TransformOperationsTest.java	Fri Sep 12 09:34:50 2014 +0200
@@ -778,15 +778,31 @@
     public void testTransformBounds() {
         Bounds result = t.transform(new BoundingBox(10, 11, 12, 13, 14, 15));
 
-        Point3D expected1 = new Point3D(
-            t.getMxx() * 10 + t.getMxy() * 11 + t.getMxz() * 12 + t.getTx(),
-            t.getMyx() * 10 + t.getMyy() * 11 + t.getMyz() * 12 + t.getTy(),
-            t.getMzx() * 10 + t.getMzy() * 11 + t.getMzz() * 12 + t.getTz());
+        Point3D[] points = new Point3D[] {
+                new Point3D(10, 11, 12),
+                new Point3D(10, 11, 27),
+                new Point3D(10, 25, 12),
+                new Point3D(10, 25, 27),
+                new Point3D(23, 11, 12),
+                new Point3D(23, 11, 27),
+                new Point3D(23, 25, 12),
+                new Point3D(23, 25, 27),
+        };
 
-        Point3D expected2 = new Point3D(
-            t.getMxx() * 23 + t.getMxy() * 25 + t.getMxz() * 27 + t.getTx(),
-            t.getMyx() * 23 + t.getMyy() * 25 + t.getMyz() * 27 + t.getTy(),
-            t.getMzx() * 23 + t.getMzy() * 25 + t.getMzz() * 27 + t.getTz());
+        Point3D expected1 = new Point3D(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
+        Point3D expected2 = new Point3D(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
+
+        for (Point3D p : points) {
+            Point3D tp = new Point3D(
+                    t.getMxx() * p.getX() + t.getMxy() * p.getY() + t.getMxz() * p.getZ() + t.getTx(),
+                    t.getMyx() * p.getX() + t.getMyy() * p.getY() + t.getMyz() * p.getZ() + t.getTy(),
+                    t.getMzx() * p.getX() + t.getMzy() * p.getY() + t.getMzz() * p.getZ() + t.getTz());
+            expected1 = new Point3D(Math.min(expected1.getX(), tp.getX()), Math.min(expected1.getY(), tp.getY()),
+                    Math.min(expected1.getZ(), tp.getZ()));
+            expected2 = new Point3D(Math.max(expected2.getX(), tp.getX()), Math.max(expected2.getY(), tp.getY()),
+                    Math.max(expected2.getZ(), tp.getZ()));
+
+        }
 
         assertEquals(expected1.getX(), result.getMinX(), 0.00001);
         assertEquals(expected1.getY(), result.getMinY(), 0.00001);
@@ -1202,15 +1218,31 @@
                 fail("Should have thrown NonInvertibleTransformException");
             }
 
-            Point3D expected1 = new Point3D(
-                it.getMxx() * 10 + it.getMxy() * 11 + it.getMxz() * 12 + it.getTx(),
-                it.getMyx() * 10 + it.getMyy() * 11 + it.getMyz() * 12 + it.getTy(),
-                it.getMzx() * 10 + it.getMzy() * 11 + it.getMzz() * 12 + it.getTz());
+            Point3D[] points = new Point3D[] {
+                    new Point3D(10, 11, 12),
+                    new Point3D(10, 11, 27),
+                    new Point3D(10, 25, 12),
+                    new Point3D(10, 25, 27),
+                    new Point3D(23, 11, 12),
+                    new Point3D(23, 11, 27),
+                    new Point3D(23, 25, 12),
+                    new Point3D(23, 25, 27),
+            };
 
-            Point3D expected2 = new Point3D(
-                it.getMxx() * 23 + it.getMxy() * 25 + it.getMxz() * 27 + it.getTx(),
-                it.getMyx() * 23 + it.getMyy() * 25 + it.getMyz() * 27 + it.getTy(),
-                it.getMzx() * 23 + it.getMzy() * 25 + it.getMzz() * 27 + it.getTz());
+            Point3D expected1 = new Point3D(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
+            Point3D expected2 = new Point3D(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
+
+            for (Point3D p : points) {
+                Point3D tp = new Point3D(
+                        it.getMxx() * p.getX() + it.getMxy() * p.getY() + it.getMxz() * p.getZ() + it.getTx(),
+                        it.getMyx() * p.getX() + it.getMyy() * p.getY() + it.getMyz() * p.getZ() + it.getTy(),
+                        it.getMzx() * p.getX() + it.getMzy() * p.getY() + it.getMzz() * p.getZ() + it.getTz());
+                expected1 = new Point3D(Math.min(expected1.getX(), tp.getX()), Math.min(expected1.getY(), tp.getY()),
+                        Math.min(expected1.getZ(), tp.getZ()));
+                expected2 = new Point3D(Math.max(expected2.getX(), tp.getX()), Math.max(expected2.getY(), tp.getY()),
+                        Math.max(expected2.getZ(), tp.getZ()));
+
+            }
 
             assertEquals(expected1.getX(), result.getMinX(), 0.00001);
             assertEquals(expected1.getY(), result.getMinY(), 0.00001);