package MapEditor;
import javax.vecmath.*;
/**
This immutable class represents a pair of axes. Its intended use is in the implementation of {@link DesignCanvas}.
It contains a number of utility methods which are useful for working with 2D and 3D points.
*/
public class AxisPair
{
/** A constant specifying the X axis */
final public static int X = 0;
/** A constant specifying the Y axis */
final public static int Y = 1;
/** A constant specifying the Z axis */
final public static int Z = 2;
/** Horizontal axis */
final private int m_hAxis;
/** Vertical axis */
final private int m_vAxis;
/** Missing axis (the unused one of {X,Y,Z})*/
final private int m_mAxis;
/**
Construct an AxisPair from the specified axes.
Notes:
- The arguments must be AxisPair.X, AxisPair.Y or AxisPair.Z (or their integer values, clearly).
- The arguments cannot be the same.
@param hAxis The horizontal axis
@param vAxis The vertical axis
@throws java.lang.Error If incorrect values are specified for the axes or the arguments are the same
*/
public AxisPair(int hAxis, int vAxis)
{
if(hAxis < 0 || hAxis > 2) throw new java.lang.Error();
if(vAxis < 0 || vAxis > 2) throw new java.lang.Error();
if(hAxis == vAxis) throw new java.lang.Error();
m_hAxis = hAxis;
m_vAxis = vAxis;
switch(m_hAxis+m_vAxis)
{
case 1: // X and Y
{
m_mAxis = Z;
break;
}
case 2: // X and Z
{
m_mAxis = Y;
break;
}
case 3: // Y and Z
{
m_mAxis = X;
break;
}
default:
{
throw new java.lang.Error();
}
}
}
/**
Given a 2D offset (in level coordinates), figure out which of the components of the
3D point p its components correspond to, and add the offset accordingly.
Example:
- The axis-pair (X,Y), p = (1,2,3), offset = (4,5) -> result = (5,7,3).
@param p The 3D point to which to add the offset
@param offset The 2D offset to add to it
*/
public void add_offset(Point3d p, final Point2d offset)
{
switch(m_hAxis)
{
case X:
p.x += offset.x;
break;
case Y:
p.y += offset.x;
break;
case Z:
p.z += offset.x;
break;
}
switch(m_vAxis)
{
case X:
p.x += offset.y;
break;
case Y:
p.y += offset.y;
break;
case Z:
p.z += offset.y;
break;
}
}
/**
Converts a 2D point in the plane specified by the axes to a 3D point, by mapping the
2D components to the relevant components in 3D, and then filling in the missing
component using the other parameter we pass in.
Example:
- The axis-pair (X,Z), p = (2,4), missingComponent = 5 -> result = (2,5,4)
@param p The 2D point in the plane
@param missingComponent The value to set for the extra component resulting from our move from 2D to 3D
@return The 3D point generated
*/
public Point3d generate_3D_point(final Point2d p, double missingComponent)
{
Point3d ret = new Point3d();
switch(m_hAxis)
{
case X:
ret.x = p.x;
break;
case Y:
ret.y = p.x;
break;
case Z:
ret.z = p.x;
break;
}
switch(m_vAxis)
{
case X:
ret.x = p.y;
break;
case Y:
ret.y = p.y;
break;
case Z:
ret.z = p.y;
break;
}
set_missing_component(ret, missingComponent);
return ret;
}
/**
Gets the component of the 3D point which is on the missing axis.
Example:
- The axis-pair (X,Z), p = (3,4,5) -> result = 4
@param p The 3D point
@return ...think about it...
*/
public double get_missing_component(final Point3d p)
{
switch(m_mAxis)
{
case X:
return p.x;
case Y:
return p.y;
case Z:
return p.z;
}
throw new java.lang.Error();
}
/**
Get a string representing the vertical axis.
@return ...think about it...
*/
public String get_vAxis_string()
{
switch(m_vAxis)
{
case X:
return "X".intern();
case Y:
return "Y".intern();
case Z:
return "Z".intern();
}
throw new java.lang.Error();
}
/**
Get a string representing the horizontal axis.
@return ...think about it...
*/
public String get_hAxis_string()
{
switch(m_hAxis)
{
case X:
return "X".intern();
case Y:
return "Y".intern();
case Z:
return "Z".intern();
}
throw new java.lang.Error();
}
/**
Returns whether the axes are a natural (ordered) pair. By this, I mean that given an AxisPair (h,v),
the cross-product of unit vectors along h and v gives us a unit vector along the missing axis, rather
than the negation of the same. In other words, (x,y), (y,z) and (z,x) are natural pairs, whereas the
others, namely (y,x), (z,y) and (x,z) are not.
@return ...think about it...
*/
public boolean natural_pair()
{
return (m_hAxis + 1) % 3 == m_vAxis;
}
/**
Scales the components in the 3D point which correspond to those of the 2D point.
Example:
- The axis-pair (X,Z), dest = (2,4,2), src = (3,4) -> result = (6,4,8)
@param dest The 3D point whose components we wish to scale
@param src The 2D point containing the scaling factors
*/
public void scale_relevant_components(Point3d dest, final Point2d src)
{
switch(m_hAxis)
{
case X:
dest.x *= src.x;
break;
case Y:
dest.y *= src.x;
break;
case Z:
dest.z *= src.x;
break;
}
switch(m_vAxis)
{
case X:
dest.x *= src.y;
break;
case Y:
dest.y *= src.y;
break;
case Z:
dest.z *= src.y;
break;
}
}
/**
Converts a 3D point to a 2D point in the plane specified by the axes, by selecting the
relevant components of the 3D point. In this case, what I mean by the X-Y plane (for
example), is the plane z = 0 (or, for that matter, z = anything). This is essentially
doing an orthographic projection.
Example:
- The axis-pair (Z,Y), p = (3,4,5) -> result = (5,4)
@param p The 3D point to convert to 2D
@return The 2D point obtained by projecting the 3D point onto the 2D axes
*/
public Point2d select_components(final Point3d p)
{
Point2d ret = new Point2d();
switch(m_hAxis)
{
case X:
ret.x = p.x;
break;
case Y:
ret.x = p.y;
break;
case Z:
ret.x = p.z;
break;
}
switch(m_vAxis)
{
case X:
ret.y = p.x;
break;
case Y:
ret.y = p.y;
break;
case Z:
ret.y = p.z;
break;
}
return ret;
}
/**
Sets the component of the 3D point which is on the missing axis.
Example:
- The axis-pair (X,Z), p = (3,?,5), missingComponent = 4 -> result = (3,4,5)
- In this, the ? means that the number isn't relevant, since it will be overwritten.
@param p The 3D point
@param missingComponent The value to which to set the component on the missing axis
*/
public void set_missing_component(Point3d p, double missingComponent)
{
switch(m_mAxis)
{
case X:
p.x = missingComponent;
break;
case Y:
p.y = missingComponent;
break;
case Z:
p.z = missingComponent;
break;
}
}
/**
Sets the components in the 3D point which correspond to those of the 2D point.
Example:
- The axis-pair (X,Z), dest = (?,4,?), src = (3,6) -> result = (3,4,6)
- In this, the ? means that the number isn't relevant, since it will be overwritten.
@param dest The 3D point whose components we wish to set
@param src The 2D point
*/
public void set_relevant_components(Point3d dest, final Point2d src)
{
switch(m_hAxis)
{
case X:
dest.x = src.x;
break;
case Y:
dest.y = src.x;
break;
case Z:
dest.z = src.x;
break;
}
switch(m_vAxis)
{
case X:
dest.x = src.y;
break;
case Y:
dest.y = src.y;
break;
case Z:
dest.z = src.y;
break;
}
}
}