1 /**
  2  * The Render Engine
  3  * Math3D
  4  *
  5  * @fileoverview A static 3D math library with several helper methods.
  6  *
  7  * @author: Brett Fattori (brettf@renderengine.com)
  8  * @author: $Author: bfattori@gmail.com $
  9  * @version: $Revision: 1570 $
 10  *
 11  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 12  *
 13  * Permission is hereby granted, free of charge, to any person obtaining a copy
 14  * of this software and associated documentation files (the "Software"), to deal
 15  * in the Software without restriction, including without limitation the rights
 16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 17  * copies of the Software, and to permit persons to whom the Software is
 18  * furnished to do so, subject to the following conditions:
 19  *
 20  * The above copyright notice and this permission notice shall be included in
 21  * all copies or substantial portions of the Software.
 22  *
 23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 29  * THE SOFTWARE.
 30  *
 31  */
 32 "use strict";
 33 
 34 // The class this file defines and its required classes
 35 R.Engine.define({
 36     "class":"R.math.Math3D",
 37     "requires":[
 38         "R.math.Point2D",
 39         "R.math.Point3D",
 40         "R.math.Vector2D",
 41         "R.math.Vector3D"
 42     ],
 43 
 44     "includes":[
 45         "/../engine/libs/sylvester.js"
 46     ]
 47 });
 48 
 49 /**
 50  * @class A static class with methods and fields that are helpful
 51  * when dealing with two dimensional mathematics.
 52  *
 53  * @static
 54  */
 55 R.math.Math3D = /** @scope R.math.Math3D.prototype */{
 56 
 57     /**
 58      * The 30° isometic projection (NEN/ISO)
 59      * @type {Number}
 60      */
 61     ISOMETRIC_PROJECTION:1,
 62 
 63     /**
 64      * The dimetric 1:2 top projection
 65      * @type {Number}
 66      */
 67     DIMETRIC_TOP_PROJECTION:2,
 68 
 69     /**
 70      * The dimetric 1:2 side projection
 71      * @type {Number}
 72      */
 73     DIMETRIC_SIDE_PROJECTION:3,
 74 
 75     /**
 76      * Project a 2d point to 3d, using one of three projection types: {@link R.math.Math3D#ISOMETRIC_PROJECTION}
 77      * <i>(default)</i>, {@link R.math.Math3D#DIMETRIC_SIDE_PROJECTION}, or
 78      * {@link R.math.Math3D#DIMETRIC_TOP_PROJECTION}.
 79      * <p/>
 80      * Reference: <a href="http://www.compuphase.com/axometr.htm">http://www.compuphase.com/axometr.htm</a>
 81      *
 82      * @param point2d {R.math.Point2D} The point to project into 3 dimensions
 83      * @param height {Number} The height of the ground.  We must use a particular height to
 84      *         extrapolate our 3D coordinates from.  If the ground is considered level, this can remain zero.
 85      * @param projectionType {Number} One of the three projection types in {@link R.math.Math2D}
 86      * @return {R.math.Point3D} This point, projected into 3 dimensions
 87      */
 88     project:function (point2d, height, projectionType) {
 89         height = height || 0;
 90         projectionType = projectionType || R.math.Math3D.ISOMETRIC_PROJECTION;
 91         var pt = R.math.Point3D.create(0, 0, 0);
 92         switch (projectionType) {
 93             case R.math.Math3D.ISOMETRIC_PROJECTION:
 94                 pt.set(0.5 * point2d.x + point2d.y - height, -(0.5 * point2d.x) + point2d.y - height, height);
 95                 break;
 96             case R.math.Math3D.DIMETRIC_SIDE_PROJECTION:
 97                 pt.set(point2d.x + (2 * (point2d.y - height)), 4 * point2d.y - height, height);
 98                 break;
 99             case R.math.Math3D.DIMETRIC_TOP_PROJECTION:
100                 pt.set(point2d.x - ((point2d.y - height) / 2), 2 * (point2d.y - height), height);
101                 break;
102         }
103         return pt;
104     },
105 
106     /**
107      * Project a 3d point to a 2d point, using one of three projection
108      * types: {@link R.math.Math3D#ISOMETRIC_PROJECTION} <i>(default)</i>, {@link R.math.Math3D#DIMETRIC_SIDE_PROJECTION}, or
109      * {@link R.math.Math3D#DIMETRIC_TOP_PROJECTION}.
110      * <p/>
111      * Reference: http://www.compuphase.com/axometr.htm
112      *
113      * @param point3d {R.math.Point3D} The point to project into 2 dimensions
114      * @param projectionType {Number} One of the three projection types in {@link R.math.Math2D}
115      * @return {R.math.Point2D} This point, projected into 2 dimensions
116      */
117     unproject:function (point3d, projectionType) {
118         projectionType = projectionType || R.math.Math3D.ISOMETRIC_PROJECTION;
119         var pt = R.math.Point2D.create(0, 0);
120         switch (projectionType) {
121             case R.math.Math3D.ISOMETRIC_PROJECTION:
122                 pt.set(point3d.x - point3d.z, point3d.y + ((point3d.x + point3d.z) / 2));
123                 break;
124             case R.math.Math3D.DIMETRIC_SIDE_PROJECTION:
125                 pt.set(point3d.x + (point3d.z / 2), point3d.y + (point3d.z / 4));
126                 break;
127             case R.math.Math3D.DIMETRIC_TOP_PROJECTION:
128                 pt.set(point3d.x + (point3d.z / 4), point3d.y + (point3d.z / 2));
129                 break;
130         }
131         return pt;
132     }
133 
134 };
135