src/demo/share/jfc/J2Ddemo/java2d/demos/Colors/Rotator3D.java
changeset 50146 0bb0e464ee76
child 52252 de9486d74a74
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jfc/J2Ddemo/java2d/demos/Colors/Rotator3D.java	Mon May 14 08:58:32 2018 -0700
@@ -0,0 +1,397 @@
+/*
+ *
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java2d.demos.Colors;
+
+
+import static java.lang.Math.PI;
+import static java.lang.Math.abs;
+import static java.lang.Math.cos;
+import static java.lang.Math.min;
+import static java.lang.Math.random;
+import static java.lang.Math.sin;
+import static java.lang.Math.sqrt;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java2d.AnimatingSurface;
+
+
+/**
+ * 3D objects with color & lighting translated, rotated and scaled.
+ */
+@SuppressWarnings("serial")
+public class Rotator3D extends AnimatingSurface {
+
+    private Objects3D objs[] = new Objects3D[3];
+    private static final int[][][] polygons = {
+        // Solid cube
+        { { 5, 1, 15, 13, 21, 23, 15 },
+            { 5, 2, 21, 13, 19, 27, 21 },
+            { 5, 3, 23, 15, 17, 25, 23 },
+            { 5, 4, 19, 13, 15, 17, 19 },
+            { 5, 5, 27, 21, 23, 25, 27 },
+            { 5, 6, 27, 19, 17, 25, 27 } },
+        // Polygonal faces cube
+        { { 5, 1, 21, 13, 19, 27, 21 },
+            { 5, 5, 23, 15, 17, 25, 23 },
+            { 4, 0, 15, 14, 16, 15 }, { 7, 6, 16, 14, 13, 12, 18, 17, 16 }, { 4,
+                0, 12, 19, 18, 12 },
+            { 4, 2, 22, 21, 20, 22 }, { 7, 0, 24, 23, 22, 20, 27, 26, 24 }, { 4,
+                2, 24, 26, 25, 24 },
+            { 4, 3, 15, 13, 23, 15 }, { 4, 0, 23, 13, 21, 23 },
+            { 5, 0, 27, 26, 18, 19, 27 }, { 5, 4, 25, 17, 18, 26, 25 } },
+        // Octahedron
+        { { 4, 3, 18, 21, 16, 18 }, { 4, 1, 20, 16, 18, 20 },
+            { 4, 1, 18, 21, 16, 18 }, { 4, 3, 20, 17, 19, 20 },
+            { 4, 2, 20, 26, 27, 20 }, { 5, 3, 26, 18, 16, 27, 26 },
+            { 5, 0, 17, 24, 25, 19, 17 }, { 4, 3, 21, 25, 24, 21 },
+            { 4, 4, 18, 21, 22, 18 }, { 4, 2, 22, 21, 17, 22 },
+            { 4, 5, 20, 23, 16, 20 }, { 4, 1, 20, 23, 19, 20 },
+            { 4, 6, 21, 23, 16, 21 }, { 4, 4, 21, 23, 19, 21 },
+            { 4, 5, 20, 18, 22, 20 }, { 4, 6, 20, 22, 17, 20 } }
+    };
+    private static final double[][][] points = {
+        // Points for solid cube & polygonal faces cube
+        { { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, { 0, -1, 0 }, { 0, 0, 1 },
+            { 0, 0, -1 }, { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, { 0, -1, 0 },
+            { 0, 0, 1 }, { 0, 0, -1 }, { 1, 1, 0 }, { 1, 1, 1 }, { 0, 1, 1 },
+            { -1, 1, 1 }, { -1, 1, 0 }, { -1, 1, -1 }, { 0, 1, -1 },
+            { 1, 1, -1 },
+            { 1, -1, 0 }, { 1, -1, 1 }, { 0, -1, 1 }, { -1, -1, 1 },
+            { -1, -1, 0 },
+            { -1, -1, -1 }, { 0, -1, -1 }, { 1, -1, -1 } },
+        // Points for octahedron
+        { { 0, 0, 1 }, { 0, 0, -1 }, { -0.8165, 0.4714, 0.33333 },
+            { 0.8165, -0.4714, -0.33333 }, { 0.8165, 0.4714, 0.33333 },
+            { -0.8165, -0.4714, -0.33333 }, { 0, -0.9428, 0.3333 },
+            { 0, 0.9428, -0.33333 }, { 0, 0, 1 }, { 0, 0, -1 },
+            { -0.8165, 0.4714, 0.33333 }, { 0.8165, -0.4714, -0.33333 },
+            { 0.8165, 0.4714, 0.33333 }, { -0.8165, -0.4714, -0.33333 },
+            { 0, -0.9428, 0.33333 }, { 0, 0.9428, -0.33333 },
+            { -1.2247, -0.7071, 1 }, { 1.2247, 0.7071, -1 },
+            { 0, 1.4142, 1 }, { 0, -1.4142, -1 }, { -1.2247, 0.7071, -1 },
+            { 1.2247, -0.7071, 1 }, { 0.61237, 1.06066, 0 },
+            { -0.61237, -1.06066, 0 }, { 1.2247, 0, 0 },
+            { 0.61237, -1.06066, 0 }, { -0.61237, 1.06066, 0 },
+            { -1.2247, 0, 0 } }
+    };
+    private static final int[][][] faces = {
+        // Solid cube
+        { { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 0 }, { 1, 5 } },
+        // Polygonal faces cube
+        { { 1, 0 }, { 1, 1 }, { 3, 2, 3, 4 }, { 3, 5, 6, 7 }, { 2, 8, 9 }, { 2,
+                10, 11 } },
+        // Octahedron
+        { { 1, 2 }, { 1, 3 }, { 2, 4, 5 }, { 2, 6, 7 }, { 2, 8, 9 },
+            { 2, 10, 11 }, { 2, 12, 13 }, { 2, 14, 15 } }, };
+
+    public Rotator3D() {
+        setBackground(Color.white);
+    }
+
+    @Override
+    public void reset(int w, int h) {
+        objs[0] = new Objects3D(polygons[0], points[0], faces[0], w, h);
+        objs[1] = new Objects3D(polygons[1], points[0], faces[1], w, h);
+        objs[2] = new Objects3D(polygons[2], points[1], faces[2], w, h);
+    }
+
+    @Override
+    public void step(int w, int h) {
+        for (Objects3D obj : objs) {
+            if (obj != null) {
+                obj.step(w, h);
+            }
+        }
+    }
+
+    @Override
+    public void render(int w, int h, Graphics2D g2) {
+        for (Objects3D obj : objs) {
+            if (obj != null) {
+                obj.render(g2);
+            }
+        }
+    }
+
+    public static void main(String argv[]) {
+        createDemoFrame(new Rotator3D());
+    }
+
+
+    /**
+     * 3D Objects : Solid Cube, Cube & Octahedron with polygonal faces.
+     */
+    public class Objects3D {
+
+        private final int UP = 0;
+        private final int DOWN = 1;
+        private int[][] polygons;
+        private double[][] points;
+        private int npoint;
+        private int[][] faces;
+        private int nface;
+        private int ncolour = 10;
+        private Color[][] colours = new Color[ncolour][7];
+        private double[] lightvec = { 0, 1, 1 };
+        private double Zeye = 10;
+        private double angle;
+        private Matrix3D orient, tmp, tmp2, tmp3;
+        private int scaleDirection;
+        private double scale, scaleAmt;
+        private double ix = 3.0, iy = 3.0;
+        private double[][] rotPts;
+        private int[][] scrPts;
+        private int xx[] = new int[20];
+        private int yy[] = new int[20];
+        private double x, y;
+        private int p, j;
+        private int colour;
+        private double bounce, persp;
+
+        public Objects3D(int[][] polygons,
+                double[][] points,
+                int[][] faces,
+                int w,
+                int h) {
+
+            this.polygons = polygons;
+            this.points = points;
+            this.faces = faces;
+            npoint = points.length;
+            nface = faces.length;
+
+            x = w * random();
+            y = h * random();
+
+            ix = random() > 0.5 ? ix : -ix;
+            iy = random() > 0.5 ? iy : -iy;
+
+            rotPts = new double[npoint][3];
+            scrPts = new int[npoint][2];
+
+            for (int i = 0; i < ncolour; i++) {
+                int val = 255 - (ncolour - i - 1) * 100 / ncolour;
+                Color[] c = {
+                    new Color(val, val, val), // white
+                    new Color(val, 0, 0), // red
+                    new Color(0, val, 0), // green
+                    new Color(0, 0, val), // blue
+                    new Color(val, val, 0), // yellow
+                    new Color(0, val, val), // cyan
+                    new Color(val, 0, val) // magenta
+                };
+                colours[i] = c;
+            }
+
+            double len = sqrt(lightvec[0] * lightvec[0] + lightvec[1]
+                    * lightvec[1] + lightvec[2] * lightvec[2]);
+            lightvec[0] = lightvec[0] / len;
+            lightvec[1] = lightvec[1] / len;
+            lightvec[2] = lightvec[2] / len;
+
+            double max = 0;
+            for (int i = 0; i < npoint; i++) {
+                len = sqrt(points[i][0] * points[i][0] + points[i][1]
+                        * points[i][1] + points[i][2] * points[i][2]);
+                if (len > max) {
+                    max = len;
+                }
+            }
+
+            for (int i = 0; i < nface; i++) {
+                len = sqrt(points[i][0] * points[i][0] + points[i][1]
+                        * points[i][1] + points[i][2] * points[i][2]);
+                points[i][0] = points[i][0] / len;
+                points[i][1] = points[i][1] / len;
+                points[i][2] = points[i][2] / len;
+            }
+
+            orient = new Matrix3D();
+            tmp = new Matrix3D();
+            tmp2 = new Matrix3D();
+            tmp3 = new Matrix3D();
+            tmp.Rotation(2, 0, PI / 50);
+            CalcScrPts((double) w / 3, (double) h / 3, 0);
+
+            scale = min(w / 3 / max / 1.2, h / 3 / max / 1.2);
+            scaleAmt = scale;
+            scale *= random() * 1.5;
+            scaleDirection = scaleAmt < scale ? DOWN : UP;
+        }
+
+        private Color getColour(int f, int index) {
+            colour = (int) ((rotPts[f][0] * lightvec[0] + rotPts[f][1]
+                    * lightvec[1] + rotPts[f][2] * lightvec[2]) * ncolour);
+            if (colour < 0) {
+                colour = 0;
+            }
+            if (colour > ncolour - 1) {
+                colour = ncolour - 1;
+            }
+            return colours[colour][polygons[faces[f][index]][1]];
+        }
+
+        private void CalcScrPts(double x, double y, double z) {
+            for (p = 0; p < npoint; p++) {
+
+                rotPts[p][2] = points[p][0] * orient.M[2][0]
+                        + points[p][1] * orient.M[2][1]
+                        + points[p][2] * orient.M[2][2];
+
+                rotPts[p][0] = points[p][0] * orient.M[0][0]
+                        + points[p][1] * orient.M[0][1]
+                        + points[p][2] * orient.M[0][2];
+
+                rotPts[p][1] = -points[p][0] * orient.M[1][0]
+                        - points[p][1] * orient.M[1][1]
+                        - points[p][2] * orient.M[1][2];
+            }
+            for (p = nface; p < npoint; p++) {
+                rotPts[p][2] += z;
+                persp = (Zeye - rotPts[p][2]) / (scale * Zeye);
+                scrPts[p][0] = (int) (rotPts[p][0] / persp + x);
+                scrPts[p][1] = (int) (rotPts[p][1] / persp + y);
+            }
+        }
+
+        private boolean faceUp(int f) {
+            return (rotPts[f][0] * rotPts[nface + f][0] + rotPts[f][1] * rotPts[nface
+                    + f][1] + rotPts[f][2] * (rotPts[nface + f][2] - Zeye) < 0);
+        }
+
+        public void step(int w, int h) {
+            x += ix;
+            y += iy;
+            if (x > w - scale) {
+                x = w - scale - 1;
+                ix = -w / 100 - 1;
+            }
+            if (x - scale < 0) {
+                x = 2 + scale;
+                ix = w / 100 + random() * 3;
+            }
+            if (y > h - scale) {
+                y = h - scale - 2;
+                iy = -h / 100 - 1;
+            }
+            if (y - scale < 0) {
+                y = 2 + scale;
+                iy = h / 100 + random() * 3;
+            }
+
+            angle += random() * 0.15;
+            tmp3.Rotation(1, 2, angle);
+            tmp2.Rotation(1, 0, angle * sqrt(2) / 2);
+            tmp.Rotation(0, 2, angle * PI / 4);
+            orient.M = tmp3.Times(tmp2.Times(tmp.M));
+            bounce = abs(cos(0.5 * (angle))) * 2 - 1;
+
+            if (scale > scaleAmt * 1.4) {
+                scaleDirection = DOWN;
+            }
+            if (scale < scaleAmt * 0.4) {
+                scaleDirection = UP;
+            }
+            if (scaleDirection == UP) {
+                scale += random();
+            }
+            if (scaleDirection == DOWN) {
+                scale -= random();
+            }
+
+            CalcScrPts(x, y, bounce);
+        }
+
+        public void render(Graphics2D g2) {
+            for (int f = 0; f < nface; f++) {
+                if (faceUp(f)) {
+                    for (j = 1; j < faces[f][0] + 1; j++) {
+                        DrawPoly(g2, faces[f][j], getColour(f, j));
+                    }
+                }
+            }
+        }
+
+        private void DrawPoly(Graphics2D g2, int poly, Color colour) {
+            for (int point = 2; point < polygons[poly][0] + 2; point++) {
+                xx[point - 2] = scrPts[polygons[poly][point]][0];
+                yy[point - 2] = scrPts[polygons[poly][point]][1];
+            }
+            g2.setColor(colour);
+            g2.fillPolygon(xx, yy, polygons[poly][0]);
+            g2.setColor(Color.black);
+            g2.drawPolygon(xx, yy, polygons[poly][0]);
+        }
+
+
+        /**
+         * A 3D matrix object.
+         */
+        public class Matrix3D {
+
+            public double[][] M = { { 1, 0, 0 },
+                { 0, 1, 0 },
+                { 0, 0, 1 } };
+            private double[][] tmp = new double[3][3];
+            private int row, col, k;
+
+            public void Rotation(int i, int j, double angle) {
+                for (row = 0; row < 3; row++) {
+                    for (col = 0; col < 3; col++) {
+                        if (row != col) {
+                            M[row][col] = 0.0;
+                        } else {
+                            M[row][col] = 1.0;
+                        }
+                    }
+                }
+                M[i][i] = cos(angle);
+                M[j][j] = cos(angle);
+                M[i][j] = sin(angle);
+                M[j][i] = -sin(angle);
+            }
+
+            public double[][] Times(double[][] N) {
+                for (row = 0; row < 3; row++) {
+                    for (col = 0; col < 3; col++) {
+                        tmp[row][col] = 0.0;
+                        for (k = 0; k < 3; k++) {
+                            tmp[row][col] += M[row][k] * N[k][col];
+                        }
+                    }
+                }
+                return tmp;
+            }
+        } // End Matrix3D
+    } // End Objects3D
+} // End Rotator3D
+