aboutsummaryrefslogblamecommitdiffstats
path: root/src/v/VMaths.java
blob: d52c12a1c18309923ddee5b5c0ad45e35f10a8c0 (plain) (tree)






























                                                                                  


                                                                           

                                                     




                                                                     




                                   
                                        



                      
                                        


                      
                               











































































































































































                                                                                         



                                            
    


































                                                                


    
/**
 * Copyright (c) 2013, Mattias Andrée
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met: 
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer. 
 * 2. 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. 
 * 
 * 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 v;

/**
 * Orthonormalised vector maths
 */
public class VMaths
{
    public static final float[][] UNIT = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
    
    
    public static float[] createRotation(String side)
    {
	return createRotation(side, UNIT);
    }
    
    public static float[] createRotation(String side, float[][] proj)
    {
	switch (side.toLowerCase())
	{
	    case "x":
	    case "xz":
	    case "zx":
		return mul(-1, proj[1]);
	    
	    case "y":
	    case "yz":
	    case "zy":
		return mul(-1, proj[0]);
	    
	    case "xy":
	    case "yx":
		return proj[2];
	}
	
	return null;
    }
    
    public static float[][] createRotation(String side, float thetaDegrees)
    {
	switch (side.toLowerCase())
	{
	    case "x":
	    case "xz":
	    case "zx":
		return createRotation( 0f, -1f,  0f, thetaDegrees);
	    
	    case "y":
	    case "yz":
	    case "zy":
		return createRotation(-1f,  0f,  0f, thetaDegrees);
	    
	    case "xy":
	    case "yx":
		return createRotation( 0f,  0f, +1f, thetaDegrees);
	}
	
	return null;
    }
    
    public static float[][] createRotation(float x, float y, float z, float thetaDegrees)
    {
	float theta = thetaDegrees * (float)(Math.PI) / 180f;
	float[][] m = new float[3][3];
	
	float cos = (float)(Math.cos(theta));
	float sin = (float)(Math.sin(theta));
	float _cos = 1f - cos;
	
	m[0][0] = x * x * _cos + cos;
	m[1][0] = x * y * _cos + z * sin;
	m[2][0] = x * z * _cos - y * sin;
	
	m[0][1] = y * x * _cos - z * sin;
	m[1][1] = y * y * _cos + cos;
	m[2][1] = y * z * _cos + x * sin;
	
	m[0][2] = z * x * _cos + y * sin;
	m[1][2] = z * y * _cos - x * sin;
	m[2][2] = z * z * _cos + cos;
	
	return m;
    }
    
    public static float[][] createRotation(float[] v, float thetaDegrees)
    {
	return createRotation(v[0], v[1], v[2], thetaDegrees);
    }
    
    public static float[] mul(float[][] m, float[] v)
    {
	int n, k = v.length;
	float[] rc = new float[n = m.length];
	
	for (int r = 0; r < n; r++)
	    for (int i = 0; i < k; i++)
		rc[r] += m[r][i] * v[i];
	
	return rc;
    }
    
    public static float[] mul(float[][] m, float x, float y, float z)
    {
	int n;
	float[] rc = new float[n = m.length];
	
	for (int i = 0; i < n; i++)
	    rc[i] = m[i][0] * x
		  + m[i][1] * y
		  + m[i][2] * z;
	
	return rc;
    }
    
    public static float[][] mul(float[][] a, float[][] b)
    {
	int n, m, k = b.length;
	float[][] rc = new float[n = a.length][m = b[0].length];
	
	for (int r = 0; r < n; r++)
	    for (int c = 0; c < m; c++)
		for (int i = 0; i < k; i++)
		    rc[r][c] += a[i][r] * b[c][i];
	
	return rc;
    }
    
    public static float[][] mul(float a, float[][] b)
    {
	int n, m;
	float[][] rc = new float[n = b.length][m = b[0].length];
	
	for (int r = 0; r < n; r++)
	    for (int c = 0; c < m; c++)
		rc[r][c] = a * b[r][c];
	
	return rc;
    }
    
    public static float[] mul(float a, float[] b)
    {
	int n;
	float[] rc = new float[n = b.length];
	
	for (int r = 0; r < n; r++)
	    rc[r] = a * b[r];
	
	return rc;
    }
    
    public static float[][] add(float[][] a, float[][] b)
    {
	int n, m;
	float[][] rc = new float[n = a.length][m = b[0].length];
	
	for (int r = 0; r < n; r++)
	    for (int c = 0; c < m; c++)
		rc[r][c] = a[r][c] + b[r][c];
	
	return rc;
    }
    
    public static float[] add(float[] a, float[] b)
    {
	int n;
	float[] rc = new float[n = a.length];
	
	for (int r = 0; r < n; r++)
	    rc[r] = a[r] + b[r];
	
	return rc;
    }
    
    public static float length(float[] v)
    {
	int n = v.length;
	float length = 0;
	
	for (int r = 0; r < n; r++)
	    length += v[r] * v[r];
	
	length = (float)Math.sqrt(length);
	
	return length;
    }
    
    public static float[] normalise(float[] v)
    {
	int n;
	float[] rc = new float[n = v.length];
	float length = length(v);
	
	if (length * length == 0f)
	{
	    for (int r = 0; r < n; r++)
		rc[r] = 0;
	    rc[0] = 1;
	}
	else
	    for (int r = 0; r < n; r++)
		rc[r] = v[r] / length;
	
	return rc;
    }
    
    public static float[][] inv(float[][] m)
    {
	return mul(1f / det(m), trans(m));
    }
    
    public static float[][] trans(float[][] m)
    {
	int x, y;
	float[][] rc = new float[y = m[0].length][x = m.length];

	for (int r = 0; r < y; r++)
            for (int c = 0; c < x; c++)
		rc[r][c] = m[c][r];
	
	return rc;
    }
    
    public static float det(float[][] m)
    {
	float rc = 0;
	int mul = 1;
	int n = m.length;
	
	if (n == 0)  return 1;
	if (n == 1)  return m[0][0];
	
	for (int i = 0; i < n; i++)
	{
	    float[][] sub = new float[n - 1][n - 1];
	    
	    for (int y = 0; y < n - 1; y++)
		for (int x = 0; x < n - 1; x++)
		    sub[y][x] = m[y + 1][x < i ? x : x + 1];
	    
	    rc += mul * det(sub);
	    mul *= -1;
	}
	
	return rc;
    }
    
}