sim.portrayal3d.simple.Arrow Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.portrayal3d.simple;
import com.sun.j3d.utils.geometry.*;
import java.awt.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import sim.util.*;
import sim.portrayal3d.SimplePortrayal3D;
/**
*
* @author Gabriel Balan
*
* This file was initially taken from http://www.j3d.org/downloads/Arrow.java
*
* and heavily modified
*/
public class Arrow extends TransformGroup
{
static final Color DEFAULT_ARROW_COLOR = Color.gray;
static final Font3D DEFAULT_FONT3D = new Font3D(new Font(null, Font.PLAIN, 1), null);
Cone arrowHead;
Cylinder arrowTail;
public Cylinder getArrowTail() { return arrowTail; }
public Cone getArrowHead() { return arrowHead; }
/**
* Creates a 3D arrow between points startPoint
and
* endPoint
if either label is not null, it adds a Text2D object
* at the appropriate end.
*/
public Arrow(double arrowTailRadius, Double3D startPoint, Double3D endPoint, String stLabel,
String endLabel, Appearance appearance)
{
Vector3d stPt = new Vector3d(startPoint.x, startPoint.y, startPoint.z);
Vector3d endPt = new Vector3d(endPoint.x, endPoint.y, endPoint.z);
Vector3d v = new Vector3d(stPt);
v.negate();
v.add(new Vector3d(endPt));
// v= start -> end
float arrowLen = (float) v.length();
float arrowHeadLen = 5.0f * (float)arrowTailRadius;
float arrowHeadMaxRadius = 3.0f * (float)arrowTailRadius;
float cylinderLen = arrowLen - arrowHeadLen;
if(cylinderLen<0)
{
//this is a short arrow,
//I need a different formula
arrowHeadLen = arrowLen/16;
cylinderLen = arrowLen - arrowHeadLen;
}
// Apperance for the arrow
Appearance caAppearance = appearance;
if(caAppearance==null)
{
caAppearance = SimplePortrayal3D.appearanceForColors(DEFAULT_ARROW_COLOR, null, DEFAULT_ARROW_COLOR, DEFAULT_ARROW_COLOR, 1.0f, 1.0f);
}
// Rotation Matrix for whole arrow (cylinder + cone)
Transform3D caTransform = new Transform3D();
caTransform.setTranslation(stPt);
Vector3d oy = new Vector3d(0, 1, 0);
Vector3d axis = new Vector3d();
axis.cross(oy, v);
//if v lies ofn Oy, then axis =[0,0,0]. No rotation is needed
if(axis.length()!=0)
{
//TODO I should use rodrigues formula here
caTransform.setRotation(new AxisAngle4d(axis, Math.asin(axis.length()
/ v.length())));
// axis.length() must be v.length() both doubles or floats, otherwise
// you might get something bigger than 1.
}
caTransform.setTranslation(stPt);
this.setTransform(caTransform);
this.arrowTail = new Cylinder((float)arrowTailRadius, cylinderLen, caAppearance);
Transform3D arrowCylinderTransform = new Transform3D();
arrowCylinderTransform.set(new Vector3f(0, cylinderLen / 2, 0));
TransformGroup arrowCylinderTransformGroup = new TransformGroup(
arrowCylinderTransform);
arrowCylinderTransformGroup.addChild(this.arrowTail);
addChild(arrowCylinderTransformGroup);
Transform3D arrowHeadTransform = new Transform3D();
arrowHeadTransform.set(new Vector3f(0, cylinderLen, 0));
TransformGroup arrowHeadTransformGroup = new TransformGroup(
arrowHeadTransform);
this.arrowHead = new Cone(arrowHeadMaxRadius, arrowHeadLen, 1, caAppearance);
arrowHeadTransformGroup.addChild(this.arrowHead);
this.addChild(arrowHeadTransformGroup);
if (stLabel != null)
{
Text3D txt = new Text3D(DEFAULT_FONT3D, stLabel);
OrientedShape3D os3d = new OrientedShape3D(txt, caAppearance,
OrientedShape3D.ROTATE_ABOUT_POINT, new Point3f(0, 0, 0));
Transform3D t = new Transform3D();
t.setScale(5 * (float)arrowTailRadius);
t.setTranslation(new Vector3f(0, -.1f, 0));
TransformGroup stLabelTG = new TransformGroup(t);
stLabelTG.addChild(os3d);
this.addChild(stLabelTG);
}
if (endLabel != null)
{
Text3D txt = new Text3D(DEFAULT_FONT3D, endLabel);
OrientedShape3D os3d = new OrientedShape3D(txt, caAppearance,
OrientedShape3D.ROTATE_ABOUT_POINT, new Point3f(0,
arrowLen, 0));
Transform3D t = new Transform3D();
t.setScale(5 * (float)arrowTailRadius);
t.setTranslation(new Vector3f(0, arrowLen + .1f, 0));
TransformGroup endLabelTG = new TransformGroup(t);
endLabelTG.addChild(os3d);
this.addChild(endLabelTG);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy