Maths - sfvec3f java

related files

/*Title:      mjbWorld
Copyright (c) 1998-2007 Martin John BakerThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.This program 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 for more details.For information about the GNU General Public License see http://www.gnu.org/To discuss this program http://sourceforge.net/forum/forum.php?forum_id=122133 also see website https://www.euclideanspace.com/ *//* for theory see: https://www.euclideanspace.com/maths/algebra/vectors/index.htm */package mjbModel; import java.io.*; // for steamtokenizer import java.lang.ref.*; import java.util.*; // for StringTokenizer /* x3d definition<!ENTITY % SFVec3f "CDATA"> <!-- Vector3Float --> *//** This class can represent a 3D vector. For instance a point in 3D space, or a relative position or movement.The class has methods to add, subtact, (cross and dot) multiply with other vectors. also many other methods, including the ability to load and save to from VRML and x3d */ public class sfvec3f extends property {/** VRML only supports float but allow override if higher resolution required */ public static boolean saveAsDouble = false ; /** x coordinate */ public double x; /** y coordinate */ public double y; /** z coordinate */ public double z;/** a constructor to set initial values of x,y and z coodinates * @param x1 value of x coordinate * @param y1 value of y coordinate * @param z1 value of z coordinate */ public sfvec3f(double x1,double y1,double z1) { x=x1; y=y1; z=z1; }/** a constructor to set initial values of x,y and z coodinates * @param x1 value of x coordinate * @param y1 value of y coordinate * @param z1 value of z coordinate */ public sfvec3f(float x1,float y1,float z1) { x=(double)x1; y=(double)y1; z=(double)z1; }/** copy constructor * @param in1 set values to save value in1 * returns a new instace with values the same as in1 */ public sfvec3f(sfvec3f in1) { x=(in1!=null) ? in1.x : 0; y= (in1!=null) ? in1.y : 0; z= (in1!=null) ? in1.z : 0; }/** construct a vector with initial value zero. */ public sfvec3f() { }/** static method to return sum of two vectors * @param a first vector to be added * @param b second vector to be added * @return the sum */ public static sfvec3f add(sfvec3f a,sfvec3f b){ return new sfvec3f(a.x + b.x,a.y + b.y,a.z + b.z); }/** static method to return difference of two vectors * @param a first vector * @param b subract this vector * @return result */ public static sfvec3f sub(sfvec3f a,sfvec3f b){ return new sfvec3f(a.x - b.x,a.y - b.y,a.z - b.z); }/** static method to give the VRML name of this vector */ public static String vrmlType_s(){ return "SFVec3f"; }/** method to give the VRML name of this vector sometimes we cant use vrmlType_s because static methods cant be overriden */ public String vrmlType(){ return "SFVec3f"; }/** overrides base clone method * @return new instance with same value of this */ public Object clone() { return new sfvec3f(this); }/** set the value of this instance to the value of other * this can be used to reuse an instance without the overheads of garbidge collection * @param other instace we want to use value of, if null then set to zero */ public void copy(sfvec3f other){ if (other==null) { x=y=z=0; return; } x= other.x; y= other.y; z= other.z; }/** subtract other vector from this * for theory see: * https://www.euclideanspace.com/maths/algebra/vectors/index.htm * @param other vector to be subtracted from this */ public void sub(sfvec3f other){ if (other==null) return; x-= other.x; y-= other.y; z-= other.z; }/** add other vector to this * for theory see: * https://www.euclideanspace.com/maths/algebra/vectors/index.htm * @param other vector to be added to this */ public void add(sfvec3f other){ if (other==null) return; x+= other.x; y+= other.y; z+= other.z; }/** inverts the direction of the vector */ public void minus() { x=-x; y=-y; z=-z; }/** return a vector pointing on the opposite direction to this without affecting the * value of this instance * @return new instance with value= munus this */ public sfvec3f getMinus() { return new sfvec3f(-x,-y,-z); }/** convert this vector to unit length * for theory see: * https://www.euclideanspace.com/maths/algebra/vectors/normals/index.htm */ public void normalize(){ double t = Math.sqrt(x*x + y*y + z*z); x /= t; y /= t; z /= t; }/** scale this vector equally in all directions * @param sc scale factor */ public void scale(double sc){ x *= sc; y *= sc; z *= sc; }/** scale this vector posibly different in x,y and z directions * @param other scale value */ public void scale(sfvec3f other){ x *= other.x; y *= other.y; z *= other.z; }/** scale this vector by inverse of other * @param other scale value */ public void scaleInv(sfvec3f other){ x /= other.x; y /= other.y; z /= other.z; }/** return square of distance from end of this vector to end of other * @param other calcules distance from this vector * @return square of distance from end of this vector to end of other */ public double distanceSquared(sfvec3f other){ double x1 = other.x - x; double y1 = other.y - y; double z1 = other.z - z; return x1*x1 + y1*y1 + z1*z1; }/** cross product * for theory see: * https://www.euclideanspace.com/maths/algebra/vectors/index.htm * @param other vector to take cross product with */ public void cross(sfvec3f other) { double xh = y * other.z - other.y * z; double yh = z * other.x - other.z * x; double zh = x * other.y - other.x * y; x = xh; y = yh; z = zh; }/** dot product * for theory see: * https://www.euclideanspace.com/maths/algebra/vectors/index.htm * @param other vector to take dot product with * @return dot product */ public double dot(sfvec3f other) { return (x * other.x) + (y * other.y) + (z * other.z); }/** create an array of the appropriate type * with a size given by the parameter * @param size array size * @return new instance of sfvec3f array */ public property[] createArray(int size){ return new sfvec3f[size]; }/** set the x value only without althering the other dimensions * @param v new value for x */ public void setX(double v) { x=v; }/** set the y value only without althering the other dimensions * @param v new value for y */ public void setY(double v) { y=v; }/** set the z value only without althering the other dimensions * @param v new value for z */ public void setZ(double v) { z=v; }/** gets the value in the x dimension * @return the value in the x dimension */ public double getx() { return x; }/** gets the value in the y dimension * @return the value in the y dimension */ public double gety() { return y; }/** gets the value in the z dimension * @return the value in the z dimension */ public double getz() { return z; }/** return a string which represents the value which can be used in source code * @return a string representing the value of this */ public String toStatic() { return ""+ x + "f," + y + "f," + z + "f"; }/** returns true if any dimension of other vector is greater than the same dimension * of this * @param other vector to compare with this * @return true if greater */ public boolean greaterThan(sfvec3f other) { if (other.x > x) return true; if (other.y > y) return true; if (other.z > z) return true; return false; }/** returns true if any dimension of other vector is less than the same dimension * of this * @param other vector to compare with this * @return true if less */ public boolean lessThan(sfvec3f other) { if (other.x < x) return true; if (other.y < y) return true; if (other.z < z) return true; return false; }/** returns true if this vector has an equal value to other vector * @param other vector to compare with this * @return */ public boolean equals(sfvec3f other) { if (other==null) return false; if (x!= other.x) return false; if (y!= other.y) return false; if (z!= other.z) return false; return true; }/** output as a string * @param format">mode values * 0 - output modified values * 1 - output original values * 2 - output attribute * 3 - output attribute in brackets * 4 - output with f prefix * @return string result */ public String outstring(int format) { if (format == 3) { if (saveAsDouble) return "(" + x + " " + y + " " + z + ")"; else return "(" + new Float(x).toString() + " " + new Float(y).toString() + " " + new Float(z).toString() + ")"; } else if (format == 4) { return new Float(x).toString() + "f," + new Float(y).toString() + "f," + new Float(z).toString() + "f"; } else { if (saveAsDouble) return "" + x + " " + y + " " + z; else return new Float(x).toString() + " " + new Float(y).toString() + " " + new Float(z).toString(); } } /** write to file * @param f" filter = information about output</param> * @param mode mode values * 0 - output VRML97 modified values * 1 - output VRML97 original values * 2 - output xml (x3d) * 3 - output attribute in brackets * 4 - output with f prefix</param> * @param indent * */ public void write(filter f,int mode,int indent){ if (mode == 3) { if (saveAsDouble) { f.write("(" + x + " " + y + " " + z + ")"); return; } else { f.write("(" + new Float(x).toString() + " " + new Float(y).toString() + " " + new Float(z).toString() + ")"); return; } } else if (mode == 4) { f.write(new Float(x).toString() + "f," + new Float(y).toString() + "f," + new Float(z).toString() + "f"); return; } else { if (saveAsDouble) { f.write("" + x + " " + y + " " + z); return; } else f.write(new Float(x).toString() + " " + new Float(y).toString() + " " + new Float(z).toString()); } } public boolean readX3d(filter f) { String s; s=f.nextToken(); if (s.equals("=")) { s=f.nextToken(); if (s.equals("'")) { s=f.nextToken(); if (s.equals("(")) { s=f.nextToken(); } } } x = Float.parseFloat(s); s=f.nextToken(); y = Float.parseFloat(s); s=f.nextToken(); z = Float.parseFloat(s); return true; }/** calcultes new translation when combining translations * * Rt = Ra Rb * Ct = Cb * Tt = Ra (Cb + Tb - Ca) + Ca + Ta - Cb * * for theory: * https://www.euclideanspace.com/maths/geometry/rotations/rotationAndTranslation/nonMatrix/index.htm * @param ta Ta = translation of transform a in absolute coordinates * @param ra Ra = rotation function of transform a in absolute coordinates * @param ca Ca = centre of rotation of transform a in absolute coordinates * @param b Tb = translation of transform b in coordinates of transform a * @param cb Cb = centre of rotation of transform b in coordinates of transform a * @return Tt total offset */ public sfvec3f rotationOffset(sfvec3f ta,sfrotation ra,sfvec3f ca,sfvec3f tb,sfvec3f cb) { sfvec3f result = new sfvec3f(cb); result.add(tb); result.sub(ca); if (ra != null) ra.transform(result); result.add(ca); result.add(ta); result.sub(cb); return result; }/** use to combine bounds * if i=0 take minimum otherwise maximum * @param other">vector to combine with</param> * @param i">if i=0 take minimum otherwise maximum</param> * */ public void bounds(sfvec3f other,int i){ if (i==0) { // take minimum if (other.x < x) x=other.x; if (other.y < y) y=other.y; if (other.z < z) z=other.z; } else { // take maximum if (other.x > x) x=other.x; if (other.y > y) y=other.y; if (other.z > z) z=other.z; } }/** used when reading XML * called by sfparam which is called by mfparam which is called by filter_x3d * @param val expects val to be in following format (1.0 2.0 3.0) * @param type not used * */ public void setAttribute(String val,String type){ try { int v=0; //value being read StringTokenizer st = new StringTokenizer(val,"() \t\n\r\f"); // skip these tokens while (st.hasMoreElements()) { try { switch (v) { case 0: x = Double.parseDouble(st.nextToken());break; case 1: y = Double.parseDouble(st.nextToken());break; case 2: z = Double.parseDouble(st.nextToken());break; default: st.nextToken();break; // skip token } v++; // valid number was read so goto next } catch (NumberFormatException e) { // if it is not a valid number continue while loop } } } catch (Exception e) { System.out.println("sfvec3f.setAttribute("+val+","+type+") " + e.toString()); } }/** read SFVec3f value from VRML file * used by mfparam.vrml2par * @param f * @param sfp * @param n * @param mode * @return */ public boolean instring(filter f,sfparam sfp,nodeBean n,int mode) { String s; s=f.nextToken(); if (s!=null) if (s.equals("IS")) { s=f.nextToken(); if (sfp!=null) sfp.setIs(s); return true; } x = Float.parseFloat(s); s=f.nextToken(); y = Float.parseFloat(s); s=f.nextToken(); z = Float.parseFloat(s); return true; }/** read from a string * used by mfvec3f.instring * @param f * @param s1 * @return */ public boolean instring(filter f,String s1) { String s; x = Float.parseFloat(s1); s=f.nextToken(); y = Float.parseFloat(s); s=f.nextToken(); z = Float.parseFloat(s); return true; } /** * finds the type of a class which can edit this property * * @return editor */ static public Class getEditClass(){ return sfvec3fEditor.class; } }

metadata block
see also:

 

Correspondence about this page

Book Shop - Further reading.

Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them.

cover Mathematics for 3D game Programming - Includes introduction to Vectors, Matrices, Transforms and Trigonometry. (But no euler angles or quaternions). Also includes ray tracing and some linear & rotational physics also collision detection (but not collision response).

Terminology and Notation

Specific to this page here:

 

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.