1667 行
52 KiB
JavaScript

// Copyright 2011 David Galles, University of San Francisco. 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 David Galles ``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 David Galles 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.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of the University of San Francisco
function ChangeCoordinate2D(am, w, h)
{
this.init(am, w, h);
}
ChangeCoordinate2D.prototype = new Algorithm();
ChangeCoordinate2D.prototype.constructor = ChangeCoordinate2D;
ChangeCoordinate2D.superclass = Algorithm.prototype;
ChangeCoordinate2D.XAxisYPos = 300;
ChangeCoordinate2D.XAxisStart = 100;
ChangeCoordinate2D.XAxisEnd = 700;
ChangeCoordinate2D.MATRIX_ELEM_WIDTH = 50;
ChangeCoordinate2D.MATRIX_ELEM_HEIGHT = 15;
ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING = 10;
ChangeCoordinate2D.EQUALS_SPACING = 30;
ChangeCoordinate2D.ROBOT_MATRIX_START_X = 10 + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING;
ChangeCoordinate2D.ROBOT_MATRIX_START_Y = 30;
ChangeCoordinate2D.HAND_MATRIX_START_X = 10 +2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING;
ChangeCoordinate2D.HAND_MATRIX_START_Y = 10 + 25 + 20 + 3*ChangeCoordinate2D.MATRIX_ELEM_HEIGHT;
ChangeCoordinate2D.ROBOT_POSITION_START_X = ChangeCoordinate2D.ROBOT_MATRIX_START_X + 4*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + 100;
ChangeCoordinate2D.HAND_POSITION_START_X = ChangeCoordinate2D.HAND_MATRIX_START_X + 4*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + 100;
ChangeCoordinate2D.ROBOT_POSITION_START_Y = ChangeCoordinate2D.ROBOT_MATRIX_START_Y;
ChangeCoordinate2D.HAND_POSITION_START_Y = ChangeCoordinate2D.HAND_MATRIX_START_Y;
ChangeCoordinate2D.YAxisXPos = 400;
ChangeCoordinate2D.YAxisStart = 100;
ChangeCoordinate2D.YAxisEnd = 500;
ChangeCoordinate2D.ROBOT_POINTS = [[-15,100],[15,100],[15,80],[30,80],[30,-10],[15,-10], [15, -100], [0,-100],[0,-30],[0,-100], [-15, -100],
[-15, -10], [-30, -10], [-30, 80],[-15, 80]];
ChangeCoordinate2D.HAND_POINTS = [[0,0],[-10,0],[-10,10], [-6, 10], [-6, 6], [6, 6], [6, 10], [10, 10], [10, 0]];
ChangeCoordinate2D.ROBOT_HAND_ATTACH_POINT = [0, 40];
ChangeCoordinate2D.ROBOT_MATRIX_VALUES = [[[Math.cos(Math.PI / 8), Math.sin(Math.PI / 8)],[-Math.sin(Math.PI / 8), Math.cos(Math.PI / 8)]],
[[Math.cos(Math.PI / 4), Math.sin(Math.PI / 4)],[-Math.sin(Math.PI / 4), Math.cos(Math.PI / 4)]],
[[Math.cos(0), Math.sin(0)],[-Math.sin(0), Math.cos(0)]],
[[Math.cos(3*Math.PI / 4), Math.sin(3*Math.PI/4)],[-Math.sin(3*Math.PI/4), Math.cos(3*Math.PI/4)]]];
ChangeCoordinate2D.ROBOT_POSITION_VALUES = [[75, 50], [200,100],[100,100], [100, 200]];
ChangeCoordinate2D.HAND_MATRIX_VALUES = [[[Math.cos(-Math.PI / 6), Math.sin(-Math.PI / 6)],[-Math.sin(-Math.PI / 6), Math.cos(-Math.PI / 6)]],
[[Math.cos(Math.PI / 4), Math.sin(Math.PI / 4)],[-Math.sin(Math.PI / 4), Math.cos(-Math.PI / 4)]],
[[Math.cos(0), Math.sin(0)],[-Math.sin(0), Math.cos(0)]],
[[Math.cos(Math.PI/2), Math.sin(Math.PI/2)],[-Math.sin(Math.PI/2), Math.cos(Math.PI/2)]]];
ChangeCoordinate2D.HAND_POSITION_VALUES = [[80,30],[30,90],[100,100],[-50, -20]];
//ChangeCoordinate2D.ROBOT_POINTS = [[-20, 40], [20,40],[
ChangeCoordinate2D.AXIS_CENTER = [[750,470],[750,150],[100, 550]];
ChangeCoordinate2D.AXIS_COLOR_0 = "#990000"
ChangeCoordinate2D.AXIS_COLOR_1 = "#009900"
ChangeCoordinate2D.AXIS_COLOR_2 = "#000099"
ChangeCoordinate2D.LOCAL_VERTEX_FOREGORUND_COLOR = "#000000";
ChangeCoordinate2D.LOCAL_VERTEX_BACKGROUND_COLOR = ChangeCoordinate2D.LOCAL_VERTEX_FOREGORUND_COLOR;
ChangeCoordinate2D.LOCAL_EDGE_COLOR = "#000000";
ChangeCoordinate2D.GLOBAL_VERTEX_FOREGORUND_COLOR = "#00FF00";
ChangeCoordinate2D.GLOBAL_VERTEX_BACKGROUND_COLOR = ChangeCoordinate2D.GLOBAL_VERTEX_FOREGORUND_COLOR;
ChangeCoordinate2D.GLOBAL_EDGE_COLOR = "#00FF00";
ChangeCoordinate2D.TRANSFORMED_VERTEX_FOREGORUND_COLOR = "#66FF66";
ChangeCoordinate2D.TRANSFORMED_VERTEX_BACKGROUND_COLOR = ChangeCoordinate2D.VERTEX_FOREGORUND_COLOR;
ChangeCoordinate2D.TRANSFORMED_EDGE_COLOR = "#66FF66";
ChangeCoordinate2D.TRANSFORMED_POINT_COLORS = ["#990000", "#009900", "#000099"]
ChangeCoordinate2D.VECTOR_COLOR = "#FF0000";
ChangeCoordinate2D.VERTEX_WIDTH = 3;
ChangeCoordinate2D.VERTEX_HEIGHT = ChangeCoordinate2D.VERTEX_WIDTH;
ChangeCoordinate2D.prototype.init = function(am, w, h)
{
var sc = ChangeCoordinate2D.superclass.init.call(this, am, w, h);
this.rowMajor = true;
this.posYUp = true;
this.rotateFirst = true;
this.addControls();
this.currentShape = 0;
this.commands = [];
this.nextIndex = 0;
this.PositionIndex = 0;
this.RobotPositionValues = ChangeCoordinate2D.ROBOT_POSITION_VALUES[this.PositionIndex];
this.RobotMatrixValues = ChangeCoordinate2D.ROBOT_MATRIX_VALUES[this.PositionIndex];
this.HandPositionValues = ChangeCoordinate2D.HAND_POSITION_VALUES[this.PositionIndex];
this.HandMatrixValues = ChangeCoordinate2D.HAND_MATRIX_VALUES[this.PositionIndex];
this.setupAxis();
this.robotLabel1ID = this.nextIndex++;
this.handLabel1ID = this.nextIndex++;
this.robotLabel2ID = this.nextIndex++;
this.handLabel2ID = this.nextIndex++;
this.cmd("CreateLabel", this.robotLabel1ID, "Robot Space to World Space\n(Orientation)", ChangeCoordinate2D.ROBOT_MATRIX_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y - 25, 0);
this.cmd("SetForegroundColor", this.robotLabel1ID, "#0000FF");
this.cmd("CreateLabel", this.robotLabel2ID, "Robot Space to World Space\n(Position)", ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y - 25, 0);
this.cmd("SetForegroundColor", this.robotLabel2ID, "#0000FF");
this.RobotMatrix = this.createMatrix(this.RobotMatrixValues, ChangeCoordinate2D.ROBOT_MATRIX_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y);
this.resetMatrixLabels(this.RobotMatrix);
this.HandMatrix = this.createMatrix(this.HandMatrixValues, ChangeCoordinate2D.HAND_MATRIX_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y);
this.resetMatrixLabels(this.HandMatrix);
this.cmd("CreateLabel", this.handLabel1ID, "Hand Space to Robot Space\n(Orientation)", ChangeCoordinate2D.HAND_MATRIX_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y - 25, 0);
this.cmd("SetForegroundColor", this.handLabel1ID, "#0000FF");
this.cmd("CreateLabel", this.handLabel2ID, "Hand Space to Robot Space\n(Position)", ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y - 25, 0);
this.cmd("SetForegroundColor", this.handLabel2ID, "#0000FF");
this.RobotPosition = this.createMatrix([this.RobotPositionValues], ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y);
this.resetMatrixLabels(this.RobotMatrix);
this.HandPosition = this.createMatrix([this.HandPositionValues], ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y);
this.resetMatrixLabels(this.HandMatrix);
var i;
this.RobotPointWorldIDs = new Array(ChangeCoordinate2D.ROBOT_POINTS.length);
this.RobotPointRobotIDs = new Array(ChangeCoordinate2D.ROBOT_POINTS.length);
this.HandPointWorldIDs = new Array(ChangeCoordinate2D.HAND_POINTS.length);
this.HandPointRobotIDs = new Array(ChangeCoordinate2D.HAND_POINTS.length);
this.HandPointHandIDs = new Array(ChangeCoordinate2D.HAND_POINTS.length);
this.RobotHandAttachRobotID = this.nextIndex++;
this.RobotHandAttachWorldID = this.nextIndex++;
for (i = 0; i < ChangeCoordinate2D.ROBOT_POINTS.length; i++)
{
this.RobotPointWorldIDs[i] = this.nextIndex++;
this.RobotPointRobotIDs[i] = this.nextIndex++;
}
for (i = 0; i < ChangeCoordinate2D.HAND_POINTS.length; i++)
{
this.HandPointWorldIDs[i] = this.nextIndex++;
this.HandPointRobotIDs[i] = this.nextIndex++;
this.HandPointHandIDs[i] = this.nextIndex++;
}
this.savedNextIndex = this.nextIndex;
this.setupObjects();
this.setupObjectGraphic();
this.animationManager.StartNewAnimation(this.commands);
this.animationManager.skipForward();
this.animationManager.clearHistory();
this.clearHistory();
this.animationManager.setAllLayers([0, 1]);
this.lastLocalToGlobal = true;
this.oldIDs = [];
}
ChangeCoordinate2D.prototype.addAxis = function(origin, x1, x2, y1, y2, color)
{
var idArray = [];
var originID = this.nextIndex++;
idArray.push(originID);
this.cmd("CreateRectangle", originID, "", 0, 0, origin[0], origin[1]);
this.cmd("SetAlpha", originID, 0);
var axisID = this.nextIndex++;
this.cmd("CreateRectangle", axisID, "", 0, 0, x1[0], x1[1]);
this.cmd("SetAlpha", axisID, 0);
this.cmd("Connect", originID, axisID, color, 0, 1, "");
idArray.push(axisID);
axisID = this.nextIndex++;
this.cmd("CreateRectangle", axisID, "", 0, 0, x2[0], x2[1]);
this.cmd("SetAlpha", axisID, 0);
this.cmd("Connect", originID, axisID, color, 0, 1, "");
idArray.push(axisID);
axisID = this.nextIndex++;
this.cmd("CreateRectangle", axisID, "", 0, 0, y1[0], y1[1]);
this.cmd("SetAlpha", axisID, 0);
this.cmd("Connect", originID, axisID, color, 0, 1, "");
idArray.push(axisID);
axisID = this.nextIndex++;
this.cmd("CreateRectangle", axisID, "", 0, 0, y2[0], y2[1]);
this.cmd("SetAlpha", axisID, 0);
this.cmd("Connect", originID, axisID, color, 0, 1, "");
idArray.push(axisID);
var labelID = this.nextIndex++;
this.cmd("CreateLabel", labelID, "+y", y2[0] - 10, y2[1] + 10);
this.cmd("SetForegroundColor", labelID, color);
idArray.push(labelID);
labelID = this.nextIndex++;
this.cmd("CreateLabel", labelID, "+x", x2[0] - 10, x2[1] + 10);
this.cmd("SetForegroundColor", labelID, color);
idArray.push(labelID);
return idArray;
}
ChangeCoordinate2D.prototype.transformPoint = function(point, matrix, position)
{
return this.add(this.multiply([point], matrix), [position])[0];
}
ChangeCoordinate2D.prototype.setupExtraAxes = function()
{
var robotOrigin = this.RobotPositionValues;
var x1 = this.transformPoint([-150, 0], this.RobotMatrixValues, this.RobotPositionValues);
var x2 = this.transformPoint([150, 0], this.RobotMatrixValues, this.RobotPositionValues);
var y1 = this.transformPoint([0, -150], this.RobotMatrixValues, this.RobotPositionValues);
var y2 = this.transformPoint([0, 150], this.RobotMatrixValues, this.RobotPositionValues);
this.otherAxes = [];
var tmpAxis = this.addAxis(this.worldToScreenSpace(robotOrigin, 2),
this.worldToScreenSpace(x1, 2),
this.worldToScreenSpace(x2, 2),
this.worldToScreenSpace(y1, 2),
this.worldToScreenSpace(y2, 2),
ChangeCoordinate2D.AXIS_COLOR_1);
this.otherAxes.push(tmpAxis);
for (var i = 0; i < tmpAxis.length; i++)
{
this.cmd("SetLayer", tmpAxis[i], 1);
}
this.setAxisAlpha(tmpAxis, 0.5);
var handOrigin = this.HandPositionValues;
x1 = this.transformPoint([-150, 0], this.HandMatrixValues, this.HandPositionValues);
x2 = this.transformPoint([150, 0], this.HandMatrixValues, this.HandPositionValues);
y1 = this.transformPoint([0, -150], this.HandMatrixValues, this.HandPositionValues);
y2 = this.transformPoint([0, 150], this.HandMatrixValues, this.HandPositionValues);
tmpAxis = this.addAxis(this.worldToScreenSpace(handOrigin, 1),
this.worldToScreenSpace(x1, 1),
this.worldToScreenSpace(x2, 1),
this.worldToScreenSpace(y1, 1),
this.worldToScreenSpace(y2, 1),
ChangeCoordinate2D.AXIS_COLOR_0);
for (var i = 0; i < tmpAxis.length; i++)
{
this.cmd("SetLayer", tmpAxis[i], 1);
}
this.setAxisAlpha(tmpAxis, 0.5);
this.otherAxes.push(tmpAxis);
handOrigin = this.transformPoint(handOrigin, this.RobotMatrixValues, this.RobotPositionValues);
x1 = this.transformPoint(x1, this.RobotMatrixValues, this.RobotPositionValues);
x2 = this.transformPoint(x2, this.RobotMatrixValues, this.RobotPositionValues);
y1 = this.transformPoint(y1, this.RobotMatrixValues, this.RobotPositionValues);
y2 = this.transformPoint(y2, this.RobotMatrixValues, this.RobotPositionValues);
tmpAxis = this.addAxis(this.worldToScreenSpace(handOrigin, 2),
this.worldToScreenSpace(x1, 2),
this.worldToScreenSpace(x2, 2),
this.worldToScreenSpace(y1, 2),
this.worldToScreenSpace(y2, 2),
ChangeCoordinate2D.AXIS_COLOR_0);
for (var i = 0; i < tmpAxis.length; i++)
{
this.cmd("SetLayer", tmpAxis[i], 1);
}
this.setAxisAlpha(tmpAxis, 0.5);
this.otherAxes.push(tmpAxis);
}
ChangeCoordinate2D.prototype.setupAxis = function()
{
this.axisHand = this.addAxis(this.worldToScreenSpace([0,0], 0),
this.worldToScreenSpace([-150, 0], 0),
this.worldToScreenSpace([150,0], 0),
this.worldToScreenSpace([0, -150], 0),
this.worldToScreenSpace([0, 150], 0),
ChangeCoordinate2D.AXIS_COLOR_0);
this.setAxisAlpha(this.axisHand, 0.5);
this.axisRobot = this.addAxis(this.worldToScreenSpace([0,0], 1),
this.worldToScreenSpace([-150, 0], 1),
this.worldToScreenSpace([150,0], 1),
this.worldToScreenSpace([0, -150], 1),
this.worldToScreenSpace([0, 150], 1),
ChangeCoordinate2D.AXIS_COLOR_1);
this.setAxisAlpha(this.axisRobot, 0.5);
this.axisWorld = this.addAxis(this.worldToScreenSpace([0,0], 2),
this.worldToScreenSpace([-50, 0], 2),
this.worldToScreenSpace([400,0], 2),
this.worldToScreenSpace([0, -50], 2),
this.worldToScreenSpace([0, 400], 2),
ChangeCoordinate2D.AXIS_COLOR_2);
this.setAxisAlpha(this.axisWorld, 0.5);
this.setupExtraAxes();
}
ChangeCoordinate2D.prototype.setAxisAlpha = function(axisList, newAlpha)
{
for (var i = 0; i < axisList.length; i++)
{
this.cmd("SetAlpha", axisList[i], newAlpha);
if (i > 0)
{
this.cmd("SetEdgeAlpha", axisList[0], axisList[i], newAlpha);
}
}
}
ChangeCoordinate2D.prototype.setupObjects = function()
{
var i;
for (i = 0; i < ChangeCoordinate2D.ROBOT_POINTS.length; i++)
{
var point = this.worldToScreenSpace(ChangeCoordinate2D.ROBOT_POINTS[i], 1);
this.cmd("CreateRectangle", this.RobotPointRobotIDs[i], "", 0, 0, point[0], point[1]);
if (i > 0)
{
this.cmd("Connect", this.RobotPointRobotIDs[i-1], this.RobotPointRobotIDs[i], "#000000", 0, 0);
}
point = this.transformPoint(ChangeCoordinate2D.ROBOT_POINTS[i], this.RobotMatrixValues, this.RobotPositionValues);
point = this.worldToScreenSpace(point, 2);
this.cmd("CreateRectangle", this.RobotPointWorldIDs[i], "", 0, 0, point[0], point[1]);
if (i > 0)
{
this.cmd("Connect", this.RobotPointWorldIDs[i-1], this.RobotPointWorldIDs[i], "#000000", 0, 0);
}
}
this.cmd("Connect", this.RobotPointRobotIDs[this.RobotPointRobotIDs.length - 1], this.RobotPointRobotIDs[0], "#000000", 0, 0);
this.cmd("Connect", this.RobotPointWorldIDs[this.RobotPointWorldIDs.length - 1], this.RobotPointWorldIDs[0], "#000000", 0, 0);
for (i = 0; i < ChangeCoordinate2D.HAND_POINTS.length; i++)
{
var point = this.worldToScreenSpace(ChangeCoordinate2D.HAND_POINTS[i], 0);
this.cmd("CreateRectangle", this.HandPointHandIDs[i], "", 0, 0, point[0], point[1]);
if (i > 0)
{
this.cmd("Connect", this.HandPointHandIDs[i-1], this.HandPointHandIDs[i], "#000000", 0, 0);
}
point = this.transformPoint(ChangeCoordinate2D.HAND_POINTS[i], this.HandMatrixValues, this.HandPositionValues);
var point2 = this.worldToScreenSpace(point, 1);
this.cmd("CreateRectangle", this.HandPointRobotIDs[i], "", 0, 0, point2[0], point2[1]);
if (i > 0)
{
this.cmd("Connect", this.HandPointRobotIDs[i-1], this.HandPointRobotIDs[i], "#000000", 0, 0);
}
point = this.transformPoint(point, this.RobotMatrixValues, this.RobotPositionValues);
point = this.worldToScreenSpace(point,2);
this.cmd("CreateRectangle", this.HandPointWorldIDs[i], "", 0, 0, point[0], point[1]);
if (i > 0)
{
this.cmd("Connect", this.HandPointWorldIDs[i-1], this.HandPointWorldIDs[i], "#000000", 0, 0);
}
}
this.cmd("Connect", this.HandPointHandIDs[this.HandPointHandIDs.length - 1], this.HandPointHandIDs[0], "#000000", 0, 0);
this.cmd("Connect", this.HandPointRobotIDs[this.HandPointRobotIDs.length - 1], this.HandPointRobotIDs[0], "#000000", 0, 0);
this.cmd("Connect", this.HandPointWorldIDs[this.HandPointWorldIDs.length - 1], this.HandPointWorldIDs[0], "#000000", 0, 0);
point = this.worldToScreenSpace(ChangeCoordinate2D.ROBOT_HAND_ATTACH_POINT, 1);
this.cmd("CreateRectangle", this.RobotHandAttachRobotID, "", 0, 0, point[0], point[1]);
this.cmd("Connect", this.RobotHandAttachRobotID, this.HandPointRobotIDs[0], "#000000", 0, 0);
point = this.transformPoint(ChangeCoordinate2D.ROBOT_HAND_ATTACH_POINT, this.RobotMatrixValues, this.RobotPositionValues);
point = this.worldToScreenSpace(point, 2);
this.cmd("CreateRectangle", this.RobotHandAttachWorldID, "", 0, 0, point[0], point[1]);
this.cmd("Connect", this.RobotHandAttachWorldID, this.HandPointWorldIDs[0], "#000000", 0, 0);
}
ChangeCoordinate2D.prototype.worldToScreenSpace = function(point, space)
{
var transformedPoint = new Array(2);
return [point[0] + ChangeCoordinate2D.AXIS_CENTER[space][0],
-point[1] + ChangeCoordinate2D.AXIS_CENTER[space][1]];
}
ChangeCoordinate2D.prototype.removeOldIDs = function()
{
var i;
for (i = 0; i < this.oldIDs.length; i++)
{
this.cmd("Delete", this.oldIDs[i]);
}
this.oldIDs = [];
}
ChangeCoordinate2D.prototype.setupObjectGraphic = function()
{
var i;
}
ChangeCoordinate2D.prototype.addControls = function()
{
this.controls = [];
addLabelToAlgorithmBar("x");
this.xField = addControlToAlgorithmBar("Text", "");
this.xField.onkeydown = this.returnSubmitFloat(this.xField, this.transformPointCallback.bind(this), 4, true);
this.controls.push(this.xField);
addLabelToAlgorithmBar("y");
this.yField = addControlToAlgorithmBar("Text", "");
this.yField.onkeydown = this.returnSubmitFloat(this.yField, this.transformPointCallback.bind(this), 4, true);
this.controls.push(this.yField);
var transformButton = addControlToAlgorithmBar("Button", "Transform Point");
transformButton.onclick = this.transformPointCallback.bind(this);
this.controls.push(transformButton);
var radioButtonList = addRadioButtonGroupToAlgorithmBar(["Hand Space -> World Space",
"World Space -> Hand Space",
],
"Transform Type");
this.handToWorldButton = radioButtonList[0];
this.handToWorldButton.onclick = this.transformTypeChangedCallback.bind(this, false);
this.controls.push(this.handToWorldButton);
this.worldToHandButton = radioButtonList[1];
this.worldToHandButton.onclick = this.transformTypeChangedCallback.bind(this, true);
this.controls.push(this.worldToHandButton);
this.worldToHandButton.checked = this.lastLocalToGlobal;
this.handToWorldButton.checked = !this.lastLocalToGlobal;
var radioButtonList = addRadioButtonGroupToAlgorithmBar(["Row Major",
"Column Major",
],
"RankType");
this.rowMajorButton = radioButtonList[0];
this.rowMajorButton.onclick = this.changeRowColMajorCallback.bind(this, true);
this.controls.push(this.rowMajorButton);
this.colMajorButton = radioButtonList[1];
this.colMajorButton.onclick = this.changeRowColMajorCallback.bind(this, false);
this.controls.push(this.colMajorButton);
this.rowMajorButton.checked = this.rowMajor;
this.colMajorButton.checked = !this.rowMajor;
this.showAxisBox = addCheckboxToAlgorithmBar("Show all axes");
this.showAxisBox.onclick = this.showAllAxesCallback.bind(this);
this.showAxisBox.checked = true;
//this.controls.push(this.showAxisBox);
var moveObjectsButton = addControlToAlgorithmBar("Button", "Move Objects");
moveObjectsButton.onclick = this.moveObjectsCallback.bind(this);
this.controls.push(moveObjectsButton);
}
ChangeCoordinate2D.prototype.showAllAxesCallback = function()
{
if (this.showAxisBox.checked)
{
this.animationManager.setAllLayers([0,1]);
}
else
{
this.animationManager.setAllLayers([0]);
}
}
ChangeCoordinate2D.prototype.reset = function()
{
this.rowMajor = true;
this.rowMajorButton.checked = this.rowMajor;
this.nextIndex = this.savedNextIndex;
}
ChangeCoordinate2D.prototype.enableUI = function(event)
{
for (var i = 0; i < this.controls.length; i++)
{
this.controls[i].disabled = false;
}
}
ChangeCoordinate2D.prototype.disableUI = function(event)
{
for (var i = 0; i < this.controls.length; i++)
{
this.controls[i].disabled = true;
}
}
ChangeCoordinate2D.prototype.transformTypeChangedCallback = function(globalToLocal)
{
if (this.lastLocalToGlobal == globalToLocal)
{
this.implementAction(this.changeTransformType.bind(this,globalToLocal));
}
}
ChangeCoordinate2D.prototype.changeRowColMajorCallback = function(rowMajor)
{
if (this.rowMajor != rowMajor)
{
this.implementAction(this.changeRowCol.bind(this), rowMajor);
}
}
ChangeCoordinate2D.prototype.transposeVisual = function(matrix)
{
if (matrix.data.length == matrix.data[0].length)
{
var matrixSize = matrix.data.length;
var i, j, tmp, moveLabel1, moveLabel2;
var moveLabels = [];
for (i = 1; i < matrixSize; i++)
{
for (j = 0; j <= i; j++)
{
this.cmd("SetText", matrix.dataID[i][j], "");
this.cmd("SetText", matrix.dataID[j][i], "");
moveLabel1 = this.nextIndex++;
moveLabel2 = this.nextIndex++;
moveLabels.push(moveLabel1);
moveLabels.push(moveLabel2);
this.cmd("CreateLabel", moveLabel1,
matrix.data[i][j], matrix.x + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2+ i * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
matrix.y + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2+ j * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
this.cmd("CreateLabel", moveLabel2,
matrix.data[j][i], matrix.x + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2+ j * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
matrix.y + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2 + i * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
this.cmd("Move", moveLabel1, matrix.x + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2+ j * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
matrix.y + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2 + i * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
this.cmd("Move", moveLabel2, matrix.x + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2+ i * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
matrix.y + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2 + j * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
tmp = matrix.data[i][j];
matrix.data[i][j] = matrix.data[j][i];
matrix.data[j][i] = tmp;
}
}
this.cmd("Step");
for (i = 0; i < moveLabels.length; i++)
{
this.cmd("Delete", moveLabels[i]);
}
this.resetMatrixLabels(matrix);
return matrix;
}
else
{
var savedData = matrix.data;
var newData = new Array(savedData[0].length);
var i,j;
for (i = 0; i < savedData[0].length; i++)
{
newData[i] = [];
}
for (i = 0; i < savedData.length; i++)
{
for (j = 0; j < savedData[0].length; j++)
{
newData[j][i] = savedData[i][j];
}
}
var newMatrix = this.createMatrix(newData, matrix.x, matrix.y);
this.deleteMatrix(matrix);
return newMatrix;
}
}
ChangeCoordinate2D.prototype.changeRowCol = function(rowMajor)
{
this.commands = new Array();
this.rowMajor= rowMajor;
if (this.rowMajorButton.checked != this.rowMajor)
{
this.rowMajorButton.checked = this.rowMajor;
}
if (this.colMajorButton.checked == this.rowMajor)
{
this.colMajorButton.checked = !this.rowMajor;
}
this.removeOldIDs();
this.RobotMatrix = this.transposeVisual(this.RobotMatrix);
this.RobotPosition = this.transposeVisual(this.RobotPosition);
this.HandMatrix = this.transposeVisual(this.HandMatrix);
this.HandPosition = this.transposeVisual(this.HandPosition);
return this.commands;
}
ChangeCoordinate2D.prototype.fixNumber = function(value, defaultVal)
{
if (value == "" || value == "-" || value == "." || value == "-." || isNaN(parseFloat(value)))
{
value = defaultVal;
}
else
{
value = String(parseFloat(value));
}
return value
}
ChangeCoordinate2D.prototype.transformPointCallback = function()
{
this.xField.value = this.fixNumber(this.xField.value, "0");
this.yField.value = this.fixNumber(this.yField.value, "0");
this.implementAction(this.doPointTransform.bind(this), this.xField.value + ";" + this.yField.value);
}
ChangeCoordinate2D.prototype.doPointTransform = function(params)
{
if (this.lastLocalToGlobal)
{
return this.localToGlobal(params);
}
else
{
return this.globalToLocal(params);
}
}
ChangeCoordinate2D.prototype.rotatePoint = function(point, matrix, xPos, yPos, fromSpace, toSpace)
{
var logicalPoint;
var descriptLabel = this.nextIndex++;
// this.oldIDs.push(descriptLabel);
this.cmd("CreateLabel", descriptLabel, "", xPos + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING,
yPos + 2*ChangeCoordinate2D.MATRIX_ELEM_HEIGHT + 3, 0);
var inertialPositionMatrix;
if (this.rowMajor)
{
inertialPositionMatrix = this.createMatrix([["", ""]], xPos + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING,
yPos);
}
else
{
inertialPositionMatrix = this.createMatrix([[""], [""]],
xPos + 3 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,
yPos);
}
var equalLabel1 = this.nextIndex++;
this.oldIDs.push(equalLabel1);
if (this.rowMajor)
{
opX = xPos + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING / 2;
opY = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2;
}
else
{
opX = xPos + 3 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING / 2 + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING;
opY = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT;
}
this.cmd("CreateLabel", equalLabel1, "=", opX , opY);
if (this.rowMajor)
{
this.multiplyMatrix(point, matrix, inertialPositionMatrix, descriptLabel);
}
else
{
this.multiplyMatrix(matrix, point, inertialPositionMatrix, descriptLabel);
}
this.addMatrixIDsToList(inertialPositionMatrix, this.oldIDs);
this.cmd("Delete", descriptLabel);
var inertialPositionID = this.nextIndex++;
if (this.rowMajor)
{
logicalPoint = inertialPositionMatrix.data[0].slice(0);
}
else
{
logicalPoint = [inertialPositionMatrix.data[0][0], inertialPositionMatrix.data[1][0]];
}
screenPoint = this.worldToScreenSpace(logicalPoint, fromSpace);
this.cmd("CreateCircle", inertialPositionID, "", screenPoint[0], screenPoint[1]);
this.cmd("SetWidth", inertialPositionID, ChangeCoordinate2D.VERTEX_WIDTH);
var originID = this.nextIndex++;
this.oldIDs.push(originID);
var origin = this.worldToScreenSpace([0,0], fromSpace);
this.cmd("CreateRectangle", originID, "", 0, 0, origin[0], origin[1]);
this.cmd("Connect", originID, inertialPositionID, ChangeCoordinate2D.TRANSFORMED_POINT_COLORS[toSpace], 0, 1, "");
return [inertialPositionMatrix, inertialPositionID, originID];
}
ChangeCoordinate2D.prototype.translatePoint = function(point, transVector, xPos, yPos, fromSpace, toSpace, pointID)
{
var logicalPoint = new Array(2);
var robotPositionMatrix;
if (this.rowMajor)
{
logicalPoint[0] = point.data[0][0] + transVector.data[0][0];
logicalPoint[1] = point.data[0][1] + transVector.data[0][1];
robotPositionMatrix = this.createMatrix([["", ""]], xPos + 2*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING,
yPos);
}
else
{
logicalPoint[0] = point.data[0][0] + transVector.data[0][0];
logicalPoint[1] = point.data[1][0] + transVector.data[1][0];
robotPositionMatrix = this.createMatrix([[""],[""]], xPos + ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING,
yPos);
}
var addLabel1 = this.nextIndex++;
var equalLabel3 = this.nextIndex++;
this.oldIDs.push(addLabel1);
this.oldIDs.push(equalLabel3);
var op2X, op2Y;
if (this.rowMajor)
{
opX = xPos + 2*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING / 2;
opY = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2;
op2X = xPos - ChangeCoordinate2D.EQUALS_SPACING / 2;
op2Y = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2;
}
else
{
opX = xPos + ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.EQUALS_SPACING / 2;
opY = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT;
op2X = xPos - ChangeCoordinate2D.EQUALS_SPACING / 2;
op2Y = yPos + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT;
}
this.cmd("CreateLabel", equalLabel3, "=",opX , opY);
this.cmd("CreateLabel", addLabel1, "+",op2X , op2Y);
this.addMatrix(point, transVector, robotPositionMatrix);
this.addMatrixIDsToList(robotPositionMatrix, this.oldIDs);
var screenPoint = this.worldToScreenSpace(logicalPoint, fromSpace);
var robotPositionID = this.nextIndex++;
this.cmd("CreateCircle", robotPositionID, "", screenPoint[0], screenPoint[1]);
this.cmd("SetWidth", robotPositionID, ChangeCoordinate2D.VERTEX_WIDTH);
this.cmd("Connect",pointID, robotPositionID, ChangeCoordinate2D.TRANSFORMED_POINT_COLORS[toSpace], 0, 1, "");
this.cmd("Step")
var originID = this.nextIndex++;
this.oldIDs.push(originID);
var origin = this.worldToScreenSpace([0,0], fromSpace);
this.cmd("CreateCircle", originID, "", origin[0], origin[1]);
this.cmd("SetWidth", originID, 0);
this.cmd("SetAlpha", originID, 0);
this.cmd("Connect",originID, robotPositionID, ChangeCoordinate2D.TRANSFORMED_POINT_COLORS[toSpace], 0, 1, "");
return [robotPositionMatrix, robotPositionID, originID];
}
ChangeCoordinate2D.prototype.addMultiply = function(position, transVector, rotMatrix, transX, transY, rotX, rotY, initialPointID, fromSpace, toSpace)
{
var posMatrixAndPointID = this.translatePoint(position, transVector, transX, transY, fromSpace, toSpace, initialPointID);
var newPosition = posMatrixAndPointID[0];
var pointID = posMatrixAndPointID[1];
var originID = posMatrixAndPointID[2];
this.cmd("Step");
this.cmd("Disconnect", initialPointID, pointID);
if (this.rowMajor)
{
this.moveMatrix(newPosition, rotX - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH - ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,transY)
}
else
{
this.moveMatrix(newPosition, rotX + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING, transY)
}
var posMatrixAndPointID = this.rotatePoint(newPosition, rotMatrix, rotX, rotY, fromSpace, toSpace);
this.cmd("Delete", pointID);
this.cmd("Step");
var robotPositionMatrix = posMatrixAndPointID[0];
var robotPositionID = posMatrixAndPointID[1];
var movingOriginID = posMatrixAndPointID[2];
var origin = this.worldToScreenSpace([0,0], toSpace);
this.cmd("Move", movingOriginID, origin[0], origin[1]);
var logicalPoint;
if (this.rowMajor)
{
logicalPoint = robotPositionMatrix.data[0].slice(0);
}
else
{
logicalPoint = [robotPositionMatrix.data[0][0], robotPositionMatrix.data[1][0]];
}
var screenPoint = this.worldToScreenSpace(logicalPoint, toSpace);
this.cmd("Move", robotPositionID, screenPoint[0], screenPoint[1]);
this.cmd("Step");
this.oldIDs.push(robotPositionID);
return [robotPositionMatrix, robotPositionID ];
}
ChangeCoordinate2D.prototype.multiplyAdd = function(position, rotMatrix, transVector, rotX, rotY, transX, transY, fromSpace, toSpace)
{
var posMatrixAndPointID = this.rotatePoint(position, rotMatrix, rotX, rotY, fromSpace, toSpace);
var inertialPositionMatrix = posMatrixAndPointID[0];
var inertialPositionID = posMatrixAndPointID[1];
this.cmd("Step");
if (this.rowMajor)
{
this.moveMatrix(inertialPositionMatrix, transX - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH - ChangeCoordinate2D.EQUALS_SPACING,transY)
}
else
{
this.moveMatrix(inertialPositionMatrix, transX - ChangeCoordinate2D.MATRIX_ELEM_WIDTH - ChangeCoordinate2D.EQUALS_SPACING, transY)
}
posMatrixAndPointID = this.translatePoint(inertialPositionMatrix, transVector, transX, transY, fromSpace, toSpace, inertialPositionID);
var robotPositionMatrix = posMatrixAndPointID[0];
var robotPositionID = posMatrixAndPointID[1];
var movingOriginID = posMatrixAndPointID[2];
this.oldIDs.push(robotPositionID);
var logicalPoint;
if (this.rowMajor)
{
logicalPoint = robotPositionMatrix.data[0].slice(0);
}
else
{
logicalPoint = [robotPositionMatrix.data[0][0], robotPositionMatrix.data[1][0]];
}
this.cmd("Step");
this.cmd("Delete", inertialPositionID);
origin = this.worldToScreenSpace([0,0], toSpace);
this.cmd("Move", movingOriginID, origin[0], origin[1]);
screenPoint = this.worldToScreenSpace(logicalPoint, toSpace);
this.cmd("Move", robotPositionID, screenPoint[0], screenPoint[1]);
this.cmd("Step");
return robotPositionMatrix;
}
ChangeCoordinate2D.prototype.localToGlobal = function (params)
{
this.commands = [];
this.removeOldIDs();
var paramList = params.split(";");
var x = parseFloat(paramList[0]);
var y = parseFloat(paramList[1]);
var opX, opY;
var screenPoint = this.worldToScreenSpace([x,y], 0);
var logicalPoint;
var pointInHandSpaceID = this.nextIndex++;
this.oldIDs.push(pointInHandSpaceID);
this.cmd("CreateCircle", pointInHandSpaceID, "", screenPoint[0], screenPoint[1]);
this.cmd("SetWidth", pointInHandSpaceID, ChangeCoordinate2D.VERTEX_WIDTH);
this.cmd("Connect", this.axisHand[0], pointInHandSpaceID, ChangeCoordinate2D.TRANSFORMED_POINT_COLORS[0], 0, 1, "");
var initialPointMatrix;
if (this.rowMajor)
{
initialPointMatrix = this.createMatrix([[x, y]], ChangeCoordinate2D.HAND_MATRIX_START_X - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH - ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,
ChangeCoordinate2D.HAND_MATRIX_START_Y);
}
else
{
initialPointMatrix = this.createMatrix([[x], [y]], ChangeCoordinate2D.HAND_MATRIX_START_X + 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,
ChangeCoordinate2D.HAND_MATRIX_START_Y);
}
this.addMatrixIDsToList(initialPointMatrix, this.oldIDs);
this.cmd("Step");
var robotPositionMatrix = this.multiplyAdd(initialPointMatrix, this.HandMatrix, this.HandPosition,
ChangeCoordinate2D.HAND_MATRIX_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y,
ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y,
0, 1);
if (this.rowMajor)
{
this.moveMatrix(robotPositionMatrix, ChangeCoordinate2D.ROBOT_MATRIX_START_X - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH - ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,
ChangeCoordinate2D.ROBOT_MATRIX_START_Y);
}
else
{
this.moveMatrix(robotPositionMatrix, ChangeCoordinate2D.ROBOT_MATRIX_START_X + 2* ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_MULTIPLY_SPACING,
ChangeCoordinate2D.ROBOT_MATRIX_START_Y);
}
this.multiplyAdd(robotPositionMatrix, this.RobotMatrix, this.RobotPosition,
ChangeCoordinate2D.ROBOT_MATRIX_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y,
ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y,
1, 2);
return this.commands;
}
ChangeCoordinate2D.prototype.changeTransformType = function(globalToLocal)
{
this.commands = [];
this.lastLocalToGlobal = !globalToLocal;
this.removeOldIDs();
if (globalToLocal)
{
this.cmd("SetText", this.robotLabel1ID, "World Space to Robot Space\n(Orientation)");
}
else
{
this.cmd("SetText", this.robotLabel1ID, "Robot Space to World Space\n(Orientation)");
}
this.cmd("Step");
this.RobotMatrix = this.transposeVisual(this.RobotMatrix)
if (globalToLocal)
{
this.cmd("SetText", this.robotLabel2ID, "World Space to Robot Space\n(Position)");
}
else
{
this.cmd("SetText", this.robotLabel2ID, "Robot Space to World Space\n(Position)");
}
this.cmd("Step");
this.negateMatrixVisual(this.RobotPosition);
this.cmd("Step");
if (globalToLocal)
{
this.cmd("SetText", this.handLabel1ID, "Robot Space to Hand Space\n(Orientation)");
}
else
{
this.cmd("SetText", this.handLabel1ID, "Hand Space to Robot Space\n(Orientation)");
}
this.cmd("Step");
this.HandMatrix = this.transposeVisual(this.HandMatrix)
if (globalToLocal)
{
this.cmd("SetText", this.handLabel2ID, "Robot Space to Hand Space\n(Position)");
}
else
{
this.cmd("SetText", this.handLabel2ID, "Hand Space to Robot Space\n(Position)");
}
this.cmd("Step");
this.negateMatrixVisual(this.HandPosition);
this.cmd("Step");
if (globalToLocal)
{
this.cmd("Move", this.robotLabel1ID, ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y - 25);
this.moveMatrix(this.RobotMatrix, ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y)
this.cmd("Move", this.robotLabel2ID, ChangeCoordinate2D.ROBOT_MATRIX_START_X+ ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.ROBOT_MATRIX_START_Y - 25);
this.moveMatrix(this.RobotPosition, ChangeCoordinate2D.ROBOT_MATRIX_START_X+ ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.ROBOT_MATRIX_START_Y)
this.cmd("Move", this.handLabel1ID, ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y - 25);
this.moveMatrix(this.HandMatrix, ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y);
this.cmd("Move", this.handLabel2ID, ChangeCoordinate2D.HAND_MATRIX_START_X+ ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.HAND_MATRIX_START_Y - 25);
this.moveMatrix(this.HandPosition, ChangeCoordinate2D.HAND_MATRIX_START_X+ ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.HAND_MATRIX_START_Y);
}
else
{
this.cmd("Move", this.robotLabel1ID, ChangeCoordinate2D.ROBOT_MATRIX_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y - 25);
this.moveMatrix(this.RobotMatrix, ChangeCoordinate2D.ROBOT_MATRIX_START_X, ChangeCoordinate2D.ROBOT_MATRIX_START_Y)
this.cmd("Move", this.robotLabel2ID, ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y - 25);
this.moveMatrix(this.RobotPosition, ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y)
this.cmd("Move", this.handLabel1ID, ChangeCoordinate2D.HAND_MATRIX_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y - 25);
this.moveMatrix(this.HandMatrix, ChangeCoordinate2D.HAND_MATRIX_START_X, ChangeCoordinate2D.HAND_MATRIX_START_Y);
this.cmd("Move", this.handLabel2ID, ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y - 25);
this.moveMatrix(this.HandPosition, ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y);
}
return this.commands;
}
ChangeCoordinate2D.prototype.negateMatrixVisual = function(matrix)
{
var i,j
for (i = 0; i < matrix.data.length; i++)
{
for (j = 0; j < matrix.data[i].length; j++)
{
matrix.data[i][j] = -matrix.data[i][j]
}
}
this.resetMatrixLabels(matrix);
}
ChangeCoordinate2D.prototype.globalToLocal = function(params)
{
this.commands = [];
this.removeOldIDs();
var paramList = params.split(";");
var x = parseFloat(paramList[0]);
var y = parseFloat(paramList[1]);
var opX, opY;
var screenPoint = this.worldToScreenSpace([x,y], 2);
var logicalPoint;
var pointInWorldSpaceID = this.nextIndex++;
this.oldIDs.push(pointInWorldSpaceID);
this.cmd("CreateCircle", pointInWorldSpaceID, "", screenPoint[0], screenPoint[1]);
this.cmd("SetWidth", pointInWorldSpaceID, ChangeCoordinate2D.VERTEX_WIDTH);
this.cmd("Connect", this.axisWorld[0], pointInWorldSpaceID, ChangeCoordinate2D.TRANSFORMED_POINT_COLORS[2], 0, 1, "");
var initialPointMatrix;
if (this.rowMajor)
{
initialPointMatrix = this.createMatrix([[x, y]], ChangeCoordinate2D.ROBOT_MATRIX_START_X - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
ChangeCoordinate2D.ROBOT_MATRIX_START_Y);
}
else
{
initialPointMatrix = this.createMatrix([[x], [y]], ChangeCoordinate2D.ROBOT_MATRIX_START_X - ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
ChangeCoordinate2D.ROBOT_MATRIX_START_Y);
}
this.addMatrixIDsToList(initialPointMatrix, this.oldIDs);
this.cmd("Step");
var positionAndID = this.addMultiply(initialPointMatrix, this.RobotPosition, this.RobotMatrix,
ChangeCoordinate2D.ROBOT_MATRIX_START_X + ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.ROBOT_MATRIX_START_Y,
ChangeCoordinate2D.ROBOT_POSITION_START_X, ChangeCoordinate2D.ROBOT_POSITION_START_Y,
pointInWorldSpaceID,
2, 1);
var robotPositionMatrix = positionAndID[0];
var newPositionID = positionAndID[1];
if (this.rowMajor)
{
this.moveMatrix(robotPositionMatrix, ChangeCoordinate2D.HAND_MATRIX_START_X - 2 * ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
ChangeCoordinate2D.HAND_MATRIX_START_Y);
}
else
{
this.moveMatrix(robotPositionMatrix, ChangeCoordinate2D.HAND_MATRIX_START_X - ChangeCoordinate2D.MATRIX_ELEM_WIDTH,
ChangeCoordinate2D.HAND_MATRIX_START_Y);
}
this.addMultiply(robotPositionMatrix, this.HandPosition, this.HandMatrix,
ChangeCoordinate2D.HAND_MATRIX_START_X + ChangeCoordinate2D.EQUALS_SPACING, ChangeCoordinate2D.HAND_MATRIX_START_Y,
ChangeCoordinate2D.HAND_POSITION_START_X, ChangeCoordinate2D.HAND_POSITION_START_Y,
newPositionID,
1, 0);
return this.commands;
}
ChangeCoordinate2D.prototype.moveObjectsCallback = function()
{
this.implementAction(this.moveObjects.bind(this), 0);
}
ChangeCoordinate2D.prototype.moveObjects = function()
{
this.commands = [];
this.removeOldIDs();
var i, j;
for (i = 0; i < this.otherAxes.length; i++)
{
for (j = 0; j < this.otherAxes[i].length; j++)
{
this.cmd("Delete", this.otherAxes[i][j]);
}
}
var i;
for (i = 0; i < ChangeCoordinate2D.ROBOT_POINTS.length; i++)
{
this.cmd("Delete", this.RobotPointRobotIDs[i]);
this.cmd("Delete", this.RobotPointWorldIDs[i]);
}
for (i = 0; i < ChangeCoordinate2D.HAND_POINTS.length; i++)
{
this.cmd("Delete", this.HandPointHandIDs[i]);
this.cmd("Delete", this.HandPointRobotIDs[i]);
this.cmd("Delete", this.HandPointWorldIDs[i]);
}
this.cmd("Delete", this.RobotHandAttachRobotID);
this.cmd("Delete", this.RobotHandAttachWorldID);
this.PositionIndex+= 1;
if (this.PositionIndex >= ChangeCoordinate2D.ROBOT_POSITION_VALUES.length)
{
this.PositionIndex = 0;
}
this.RobotPositionValues = ChangeCoordinate2D.ROBOT_POSITION_VALUES[this.PositionIndex];
this.RobotMatrixValues = ChangeCoordinate2D.ROBOT_MATRIX_VALUES[this.PositionIndex];
this.HandPositionValues = ChangeCoordinate2D.HAND_POSITION_VALUES[this.PositionIndex];
this.HandMatrixValues = ChangeCoordinate2D.HAND_MATRIX_VALUES[this.PositionIndex];
this.setupExtraAxes();
this.setupObjects();
this.RobotPosition.data = [this.RobotPositionValues];
this.RobotMatrix.data = this.RobotMatrixValues;
this.HandPosition.data = [this.HandPositionValues];
this.HandMatrix.data =this.HandMatrixValues;
if (!this.rowMajor)
{
this.RobotPosition.transpose();
this.RobotMatrix.transpose();
this.HandPosition.transpose();
this.HandMatrix.transpose();
}
this.resetMatrixLabels(this.RobotMatrix);
this.resetMatrixLabels(this.RobotPosition);
this.resetMatrixLabels(this.HandMatrix);
this.resetMatrixLabels(this.HandPosition);
return this.commands;
}
function toRadians(degrees)
{
return (degrees * 2 * Math.PI) / 360.0;
}
ChangeCoordinate2D.prototype.addMatrix = function(mat1, mat2, mat3)
{
var i;
var j;
for (i = 0; i < mat1.data.length; i++)
{
for (j = 0; j < mat1.data[i].length; j++)
{
explainText = "";
var value = 0;
this.cmd("SetHighlight", mat1.dataID[i][j], 1);
this.cmd("SetHighlight", mat2.dataID[i][j], 1);
this.cmd("Step");
mat3.data[i][j] = this.standardize(mat1.data[i][j] + mat2.data[i][j]);
this.cmd("SetHighlight", mat1.dataID[i][j], 0);
this.cmd("SetHighlight", mat2.dataID[i][j], 0);
this.cmd("SetText", mat3.dataID[i][j], mat3.data[i][j]);
this.cmd("Step");
}
}
}
ChangeCoordinate2D.prototype.multiplyMatrix = function(mat1, mat2, mat3, explainID)
{
var i;
var j;
var explainText = "";
for (i = 0; i < mat1.data.length; i++)
{
for (j = 0; j < mat2.data[0].length; j++)
{
var explainText = "";
var value = 0;
for (k = 0; k < mat2.data.length; k++)
{
this.cmd("SetHighlight", mat1.dataID[i][k], 1);
this.cmd("SetHighlight", mat2.dataID[k][j], 1);
if (explainText != "")
{
explainText = explainText + " + ";
}
value = value + mat1.data[i][k] * mat2.data[k][j];
explainText = explainText + String(mat1.data[i][k]) + " * " + String(mat2.data[k][j]);
this.cmd("SetText", explainID, explainText);
this.cmd("Step");
this.cmd("SetHighlight", mat1.dataID[i][k], 0);
this.cmd("SetHighlight", mat2.dataID[k][j], 0);
}
value = this.standardize(value);
explainText += " = " + String(value);
this.cmd("SetText", explainID, explainText);
mat3.data[i][j] = value;
this.cmd("SetText", mat3.dataID[i][j], value);
this.cmd("Step");
}
}
this.cmd("SetText", explainID, "");
}
ChangeCoordinate2D.prototype.standardize = function(lab)
{
var newLab = Math.round(lab * 1000) / 1000;
if (isNaN(newLab))
{
return lab;
}
else
{
return newLab;
}
}
ChangeCoordinate2D.prototype.resetMatrixLabels = function(mat)
{
var i,j;
for (i = 0; i < mat.data.length; i++)
{
for (j = 0; j < mat.data[i].length; j++)
{
mat.data[i][j] = this.standardize(mat.data[i][j]);
this.cmd("SetText", mat.dataID[i][j], mat.data[i][j]);
}
}
}
ChangeCoordinate2D.prototype.moveMatrix = function(mat, x, y)
{
var height = mat.data.length;
var width = 0;
var i, j;
for (i = 0; i < mat.data.length; i++)
{
width = Math.max(width, mat.data[i].length);
}
this.cmd("Move", mat.leftBrack1, x, y);
this.cmd("Move", mat.leftBrack2, x, y);
this.cmd("Move", mat.leftBrack3, x, y + height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
this.cmd("Move", mat.rightBrack1, x + width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y);
this.cmd("Move", mat.rightBrack2, x + width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y);
this.cmd("Move", mat.rightBrack3, x+ width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y + height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT);
for (i = 0; i < mat.data.length; i++)
{
for (j = 0; j < mat.data[i].length; j++)
{
this.cmd("Move", mat.dataID[i][j],
x + j*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2,
y + i*ChangeCoordinate2D.MATRIX_ELEM_HEIGHT + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2);
}
}
mat.x = x;
mat.y = y;
}
ChangeCoordinate2D.prototype.addMatrixIDsToList = function(mat, list)
{
list.push(mat.leftBrack1);
list.push(mat.leftBrack2);
list.push(mat.leftBrack3);
list.push(mat.rightBrack1);
list.push(mat.rightBrack2);
list.push(mat.rightBrack3);
var i,j;
for (i = 0; i < mat.data.length; i++)
{
for (j = 0; j < mat.data[i].length; j++)
{
list.push(mat.dataID[i][j]);
}
}
}
ChangeCoordinate2D.prototype.deleteMatrix = function(mat)
{
var IDList = [];
this.addMatrixIDsToList(mat, IDList);
var i;
for (i = 0; i < IDList.length; i++)
{
this.cmd("Delete", IDList[i]);
}
}
ChangeCoordinate2D.prototype.aplyFunctionToMatrixElems = function(mat, command, value)
{
this.cmd(command, mat.leftBrack1, value);
this.cmd(command, mat.leftBrack2, value);
this.cmd(command, mat.leftBrack3, value);
this.cmd(command, mat.rightBrack1, value);
this.cmd(command, mat.rightBrack2, value);
this.cmd(command, mat.rightBrack3, value);
var i,j;
for (i = 0; i < mat.data.length; i++)
{
for (j = 0; j < mat.data[i].length; j++)
{
this.cmd(command, mat.dataID[i][j], value);
}
}
}
// Multiply two (data only!) matrices (not complete matrix object with graphics, just
// the data
ChangeCoordinate2D.prototype.multiply = function(lhs, rhs)
{
var resultMat = new Array(lhs.length);
var i, j, k;
for (i = 0; i < lhs.length; i++)
{
resultMat[i] = new Array(rhs[0].length);
}
for (i = 0; i < lhs.length; i++)
{
for (j = 0; j < rhs[0].length; j++)
{
var value = 0;
for (k = 0; k < rhs.length; k++)
{
value = value + lhs[i][k] * rhs[k][j];
}
resultMat[i][j] = value;
}
}
return resultMat;
}
// Add two (data only!) matrices (not complete matrix object with graphics, just
// the data)
ChangeCoordinate2D.prototype.add = function(lhs, rhs)
{
var resultMat = new Array(lhs.length);
var i,j;
for (i = 0; i < lhs.length; i++)
{
resultMat[i] = new Array(lhs[i].length);
for (j = 0; j < lhs[i].length; j++)
{
resultMat[i][j] = lhs[i][j] + rhs[i][j];
}
}
return resultMat;
}
ChangeCoordinate2D.prototype.createMatrix = function(contents, x, y)
{
var mat = new Matrix(contents, x, y);
mat.leftBrack1 = this.nextIndex++;
mat.leftBrack2 = this.nextIndex++;
mat.leftBrack3 = this.nextIndex++;
mat.rightBrack1 = this.nextIndex++;
mat.rightBrack2 = this.nextIndex++;
mat.rightBrack3 = this.nextIndex++;
var height = mat.data.length;
var width = 0;
var i, j;
mat.dataID = new Array(mat.data.length);
for (i = 0; i < mat.data.length; i++)
{
width = Math.max(width, mat.data[i].length);
mat.dataID[i] = new Array(mat.data[i].length);
for (j = 0; j < mat.data[i].length; j++)
{
mat.dataID[i][j] = this.nextIndex++;
}
}
this.cmd("CreateRectangle", mat.leftBrack1, "", 5, 1, x, y, "left","center");
this.cmd("CreateRectangle", mat.leftBrack2, "", 1, height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT, x, y, "center","top");
this.cmd("CreateRectangle", mat.leftBrack3, "", 5, 1, x, y + height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT , "left","center");
this.cmd("CreateRectangle", mat.rightBrack1, "", 5, 1, x + width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y, "right","center");
this.cmd("CreateRectangle", mat.rightBrack2, "", 1, height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT, x + width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y, "center","top");
this.cmd("CreateRectangle", mat.rightBrack3, "", 5, 1, x+ width * ChangeCoordinate2D.MATRIX_ELEM_WIDTH, y + height * ChangeCoordinate2D.MATRIX_ELEM_HEIGHT , "right","center");
for (i = 0; i < mat.data.length; i++)
{
for (j = 0; j < mat.data[i].length; j++)
{
this.cmd("CreateLabel", mat.dataID[i][j], mat.data[i][j],
x + j*ChangeCoordinate2D.MATRIX_ELEM_WIDTH + ChangeCoordinate2D.MATRIX_ELEM_WIDTH / 2,
y + i*ChangeCoordinate2D.MATRIX_ELEM_HEIGHT + ChangeCoordinate2D.MATRIX_ELEM_HEIGHT / 2);
}
}
return mat;
}
var currentAlg;
function init()
{
var animManag = initCanvas();
currentAlg = new ChangeCoordinate2D(animManag, canvas.width, canvas.height);
}
function Matrix(contents, x, y)
{
this.data = contents;
this.x = x;
this.y = y;
}
Matrix.prototype.transpose = function()
{
var newData = new Array(this.data[0].length);
var i,j;
for (i = 0; i < this.data[0].length; i++)
{
newData[i] = new Array(this.data.length);
}
for (i = 0; i < this.data.length; i++)
{
for (j = 0; j < this.data[i].length; j++)
{
newData[j][i] = this.data[i][j];
}
}
this.data = newData;
}