// Implement a Kinematic Virtual Machine import java.util.*; public abstract class KVM extends Vector // KINEMATIC VIRTUAL MACHINE OBJECT { // DRAWING ROUTINES MUST BE IMPLEMENTED EXTERNALLY public abstract void drawLine(double x1, double y1, double x2, double y2); public abstract void drawJoint(String name, double x, double y); KVM() { // CONSTRUCTOR for (int i = 0 ; i < m.length ; i++) // BUILD THE STACK m[i] = new Matrix3D(); } public void lineTo(double x,double y,double z) { matrix(add(KVI.LINETO)).translate(x,y,z); } public void moveTo(double x,double y,double z) { matrix(add(KVI.JOINT)).translate(x,y,z); } public void joint(String name) { instr(add(KVI.JOINT)).name = name; } public void pop() { add(KVI.POP); } public void push() { add(KVI.PUSH); } public Matrix3D matrix(int i){ return instr(i).matrix; } // GET INSTR MATRIX public String name(int i) { return instr(i).name; } // GET INSTR NAME private KVI instr(int i) { return (KVI)elementAt(i); }// GET INSTRUCTION private int add(int type){ // ADD INSTRUCTION addElement(new KVI(type)); return size()-1; } private Matrix3D[] m = new Matrix3D[20]; // THE MATRIX STACK public void render() { // RENDER THE SCENE int n = 1, type; m[0].identity(); for (int i = 0 ; i < size() ; i++) if ((type = instr(i).type) == KVI.LINETO) { // DRAW A LINE double x = m[n-1].get(0,3); // FROM LOCAL double y = m[n-1].get(1,3); // ORIGIN TO m[n-1].postMultiply(matrix(i)); // TRANSFORMED drawLine(x, y, m[n-1].get(0,3), m[n-1].get(1,3)); // LOCAL ORIGIN } else if (type == KVI.JOINT) { // TRANFORM drawJoint(name(i), m[n-1].get(0,3), m[n-1].get(1,3)); m[n-1].postMultiply(matrix(i)); } else if (type == KVI.PUSH) // PUSH-COPY m[n++].set(m[n-2]); else // POP n--; } } class KVI // ONE KINEMATIC INSTRUCTION OBJECT { static final int LINETO = 0; static final int JOINT = 1; static final int POP = 2; static final int PUSH = 3; int type; String name = null; Matrix3D matrix = new Matrix3D(); KVI(int type) { this.type = type; } }