Skip to content

Commit

Permalink
I think it's done
Browse files Browse the repository at this point in the history
  • Loading branch information
DawnTheWitch committed Nov 25, 2023
1 parent b8c9392 commit e2d9713
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 107 deletions.
38 changes: 38 additions & 0 deletions src/DrawModes/DrawUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,41 @@ export function highlightNode(child: AtomNode | CutNode, color: string) {
}
}
}

/**
* Determines which widest points the current point is closest to so that the resize
* can move in that direction.
* widestPoints[0] = leftmost widest point of the ellipse
* widestPoints[1] = topmost widest point of the ellipse
* widestPoints[2] = rightmost widest point of the ellipse
* widestPoints[3] = bottommost widest point of the ellipse
* @returns The new direction for x and y
*/
export function determineDirection(currentNode: CutNode, startingPoint: Point): Point {
const newDirection = new Point(1, 1);
if (currentNode instanceof CutNode && (currentNode as CutNode).ellipse !== null) {
const currentEllipse: Ellipse = currentNode.ellipse as Ellipse;
const widestPoints: Point[] = [
new Point(currentEllipse.center.x - currentEllipse.radiusX, currentEllipse.center.y),
new Point(currentEllipse.center.x, currentEllipse.center.y - currentEllipse.radiusY),
new Point(currentEllipse.center.x + currentEllipse.radiusX, currentEllipse.center.y),
new Point(currentEllipse.center.x, currentEllipse.center.y + currentEllipse.radiusY),
];

//If the current point is closer to the top or equal the direction is positive and going down
if (widestPoints[0].distance(startingPoint) >= widestPoints[2].distance(startingPoint)) {
newDirection.x = 1;
} else {
newDirection.x = -1;
}

//If the current point is closer to the left or equal the direction is positive and going right
if (widestPoints[1].distance(startingPoint) >= widestPoints[3].distance(startingPoint)) {
newDirection.y = 1;
} else {
newDirection.y = -1;
}
}

return newDirection;
}
25 changes: 25 additions & 0 deletions src/DrawModes/EditModeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,28 @@ export function highlightChildren(child: AtomNode | CutNode, color: string) {
}
}
}

/**
* Makes a copy of original cut and changes the center and radii by the difference given.
* Alters the change to the center based on the direction that is being moved to.
* @param originalCut The original cut that will be copied and altered
* @param difference The change for the new cut
* @param direction the direction the radius will be expanding towards
* @returns The new altered cut
*/
export function resizeCut(originalCut: CutNode, difference: Point, direction: Point) {
if (originalCut.ellipse !== null) {
return new CutNode(
new Ellipse(
new Point(
originalCut.ellipse.center.x + difference.x,
originalCut.ellipse.center.y + difference.y
),
originalCut.ellipse.radiusX + difference.x * direction.x,
originalCut.ellipse.radiusY + difference.y * direction.y
)
);
} else {
throw new Error("Cannot alter the position of a cut without an ellipse.");
}
}
66 changes: 2 additions & 64 deletions src/DrawModes/ResizeTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
*/

import {Point} from "../AEG/Point";
import {Ellipse} from "../AEG/Ellipse";
import {determineDirection} from "./DrawUtils";
import {resizeCut} from "./EditModeUtils";
import {AtomNode} from "../AEG/AtomNode";
import {CutNode} from "../AEG/CutNode";
import {treeContext} from "../treeContext";
Expand Down Expand Up @@ -113,66 +114,3 @@ export function resizeMouseOut() {
legalNode = false;
redrawTree(treeContext.tree);
}

/**
* Makes a copy of original cut and changes the center and radii by the difference given.
* Alters the change to the center based on the direction that is being moved to.
* @param originalCut The original cut that will be copied and altered
* @param difference The change for the new cut
* @param direction the direction the radius will be expanding towards
* @returns The new altered cut
*/
export function resizeCut(originalCut: CutNode, difference: Point, direction: Point) {
if (originalCut.ellipse !== null) {
return new CutNode(
new Ellipse(
new Point(
originalCut.ellipse.center.x + difference.x,
originalCut.ellipse.center.y + difference.y
),
originalCut.ellipse.radiusX + difference.x * direction.x,
originalCut.ellipse.radiusY + difference.y * direction.y
)
);
} else {
throw new Error("Cannot alter the position of a cut without an ellipse.");
}
}

/**
* Determines which widest points the current point is closest to so that the resize
* can move in that direction.
* widestPoints[0] = leftmost widest point of the ellipse
* widestPoints[1] = topmost widest point of the ellipse
* widestPoints[2] = rightmost widest point of the ellipse
* widestPoints[3] = bottommost widest point of the ellipse
* @returns The new direction for x and y
*/
export function determineDirection(currentNode: CutNode, startingPoint: Point): Point {
const newDirection = new Point(1, 1);
if (currentNode instanceof CutNode && (currentNode as CutNode).ellipse !== null) {
const currentEllipse: Ellipse = currentNode.ellipse as Ellipse;
const widestPoints: Point[] = [
new Point(currentEllipse.center.x - currentEllipse.radiusX, currentEllipse.center.y),
new Point(currentEllipse.center.x, currentEllipse.center.y - currentEllipse.radiusY),
new Point(currentEllipse.center.x + currentEllipse.radiusX, currentEllipse.center.y),
new Point(currentEllipse.center.x, currentEllipse.center.y + currentEllipse.radiusY),
];

//If the current point is closer to the top or equal the direction is positive and going down
if (widestPoints[0].distance(startingPoint) >= widestPoints[2].distance(startingPoint)) {
newDirection.x = 1;
} else {
newDirection.x = -1;
}

//If the current point is closer to the left or equal the direction is positive and going right
if (widestPoints[1].distance(startingPoint) >= widestPoints[3].distance(startingPoint)) {
newDirection.y = 1;
} else {
newDirection.y = -1;
}
}

return newDirection;
}
17 changes: 5 additions & 12 deletions src/ProofTools/ProofMoveMultiTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {offset} from "../DrawModes/DragTool";
import {drawAtom, redrawTree} from "../DrawModes/DrawUtils";
import {legalColor, illegalColor} from "../Themes";
import {drawAltered, alterAtom, alterCutChildren} from "../DrawModes/EditModeUtils";
import {proofCanInsert} from "./ProofMoveSingleTool";
import {isMoveLegal} from "./ProofMoveUtils";

//The initial point the user pressed down.
let startingPoint: Point;
Expand Down Expand Up @@ -68,11 +68,11 @@ export function proofMoveMultiMouseMove(event: MouseEvent) {
redrawTree(currentProofTree);
if (currentNode instanceof CutNode) {
const tempCut: CutNode = alterCutChildren(currentNode, moveDifference);
const color = isLegal(tempCut) ? legalColor() : illegalColor();
const color = isMoveLegal(currentProofTree, tempCut) ? legalColor() : illegalColor();
drawAltered(currentNode, color, moveDifference);
} else if (currentNode instanceof AtomNode) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);
const color = isLegal(tempAtom) ? legalColor() : illegalColor();
const color = isMoveLegal(currentProofTree, tempAtom) ? legalColor() : illegalColor();
drawAtom(tempAtom, color, true);
}
}
Expand All @@ -96,15 +96,15 @@ export function proofMoveMultiMouseUp(event: MouseEvent) {
if (currentNode instanceof CutNode) {
const tempCut: CutNode = alterCutChildren(currentNode, moveDifference);

if (isLegal(tempCut)) {
if (isMoveLegal(currentProofTree, tempCut)) {
nextStep.tree.insert(tempCut);
} else {
nextStep.tree.insert(currentNode);
}
} else if (currentNode instanceof AtomNode) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);

if (isLegal(tempAtom)) {
if (isMoveLegal(currentProofTree, tempAtom)) {
nextStep.tree.insert(tempAtom);
} else {
nextStep.tree.insert(currentNode);
Expand All @@ -127,10 +127,3 @@ export function proofMoveMultiMouseOut() {
legalNode = false;
redrawTree(treeContext.getLastProofStep().tree);
}

function isLegal(currentNode: CutNode | AtomNode): boolean {
return (
currentProofTree.canInsert(currentNode) &&
proofCanInsert(new AEGTree(currentProofTree.sheet), currentNode)
);
}
34 changes: 5 additions & 29 deletions src/ProofTools/ProofMoveSingleTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {drawCut, drawAtom, redrawTree} from "../DrawModes/DrawUtils";
import {legalColor, illegalColor} from "../Themes";
import {alterAtom, alterCut} from "../DrawModes/EditModeUtils";
import {ProofNode} from "../AEG/ProofNode";
import {isMoveLegal} from "./ProofMoveUtils";

//The initial point the user pressed down.
let startingPoint: Point;
Expand Down Expand Up @@ -74,12 +75,12 @@ export function proofMoveSingleMouseMove(event: MouseEvent) {
if (currentNode instanceof CutNode) {
const tempCut: CutNode = alterCut(currentNode, moveDifference);

const color = isLegal(tempCut) ? legalColor() : illegalColor();
const color = isMoveLegal(currentProofTree, tempCut) ? legalColor() : illegalColor();
drawCut(tempCut, color);
} //If the node is an atom, make a temporary atom and check legality, drawing that.
else if (currentNode instanceof AtomNode) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);
const color = isLegal(tempAtom) ? legalColor() : illegalColor();
const color = isMoveLegal(currentProofTree, tempAtom) ? legalColor() : illegalColor();
drawAtom(tempAtom, color, true);
}
}
Expand All @@ -104,7 +105,7 @@ export function proofMoveSingleMouseUp(event: MouseEvent) {
const tempCut: CutNode = alterCut(currentNode, moveDifference);

//If the new location is legal, insert the cut otherwise reinsert the cut we removed.
if (isLegal(tempCut)) {
if (isMoveLegal(currentProofTree, tempCut)) {
nextStep.tree.insert(tempCut);
} else {
nextStep.tree.insert(currentNode);
Expand All @@ -113,7 +114,7 @@ export function proofMoveSingleMouseUp(event: MouseEvent) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);

//If the new location is legal, insert the atom, if not reinsert the atom we removed.
if (isLegal(tempAtom)) {
if (isMoveLegal(currentProofTree, tempAtom)) {
nextStep.tree.insert(tempAtom);
} else {
nextStep.tree.insert(currentNode);
Expand All @@ -136,28 +137,3 @@ export function proofMoveSingleMouseOut() {
legalNode = false;
redrawTree(treeContext.getLastProofStep().tree);
}

/**
* Determines if the current node can be inserted in a position that is not overlapping with anything
* and it being inserted would result in a graph that would equal one another.
* @param currentNode The node that will be checked for legality
* @returns Whether or no the node is in a legal position
*/
function isLegal(currentNode: CutNode | AtomNode): boolean {
return (
currentProofTree.canInsert(currentNode) &&
proofCanInsert(new AEGTree(currentProofTree.sheet), currentNode)
);
}

/**
* Inserts a copy of our current node into a copy of our current tree and compares this to a copy
* of the original tree.
* @param tree A copy of the current tree without the current node
* @param currentNode The node that will be checked for legality
* @returns Whether or not the two graphs are equal
*/
export function proofCanInsert(tree: AEGTree, currentNode: CutNode | AtomNode): boolean {
tree.insert(currentNode.copy());
return tree.isEqualTo(new AEGTree(treeContext.getLastProofStep().tree.sheet));
}
26 changes: 26 additions & 0 deletions src/ProofTools/ProofMoveUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {AEGTree} from "../AEG/AEGTree";
import {CutNode} from "../AEG/CutNode";
import {AtomNode} from "../AEG/AtomNode";
import {treeContext} from "../treeContext";

/**
* Determines if the current node can be inserted in a position that is not overlapping with anything
* and it being inserted would result in a graph that would equal one another.
* @param currentNode The node that will be checked for legality
* @returns Whether or no the node is in a legal position
*/
export function isMoveLegal(tree: AEGTree, currentNode: CutNode | AtomNode): boolean {
return tree.canInsert(currentNode) && proofCanInsert(new AEGTree(tree.sheet), currentNode);
}

/**
* Inserts a copy of our current node into a copy of our current tree and compares this to a copy
* of the original tree.
* @param tree A copy of the current tree without the current node
* @param currentNode The node that will be checked for legality
* @returns Whether or not the two graphs are equal
*/
export function proofCanInsert(tree: AEGTree, currentNode: CutNode | AtomNode): boolean {
tree.insert(currentNode.copy());
return tree.isEqualTo(new AEGTree(treeContext.getLastProofStep().tree.sheet));
}
30 changes: 28 additions & 2 deletions src/ProofTools/ProofResizeTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import {offset} from "../DrawModes/DragTool";
import {drawCut, redrawTree} from "../DrawModes/DrawUtils";
import {legalColor, illegalColor} from "../Themes";
import {ProofNode} from "../AEG/ProofNode";
import {resizeCut, determineDirection} from "../DrawModes/ResizeTool";
import {resizeCut} from "../DrawModes/EditModeUtils";
import {determineDirection} from "../DrawModes/DrawUtils";
import {ellipseLargeEnough} from "../DrawModes/CutTool";
import {proofCanInsert} from "./ProofMoveSingleTool";
import {proofCanInsert} from "./ProofMoveUtils";

//The initial point the user pressed down.
let startingPoint: Point;
Expand All @@ -32,6 +33,12 @@ let direction: Point = new Point(1, 1);
//The tree of the current proof step
let currentProofTree: AEGTree;

/**
* Takes the point the user clicked and stores that for later use. If the lowest node containing
* that point is not the sheet, then store that as currentNode and find that node's parent.
* Removes the node from the parent and reinsert its children if it has any. Cannot be an Atom.
* @param event The mouse down even while using resize tool in proof mode
*/
export function proofResizeMouseDown(event: MouseEvent) {
currentProofTree = new AEGTree(treeContext.getLastProofStep().tree.sheet);
startingPoint = new Point(event.x - offset.x, event.y - offset.y);
Expand All @@ -52,6 +59,11 @@ export function proofResizeMouseDown(event: MouseEvent) {
}
}

/**
* If the node is legal alters the center and both of the radii. Creates a copy of the current cut
* So that the original is not altered in any way.
* @param event The mouse move event while the resize tool is being used in proof mode
*/
export function proofResizeMouseMove(event: MouseEvent) {
if (legalNode) {
const moveDifference: Point = new Point(
Expand All @@ -71,6 +83,11 @@ export function proofResizeMouseMove(event: MouseEvent) {
}
}

/**
* If the node is legal creates a new temporary cut and alters the ellipse center and radii.
* If this new cut can be inserted inserts that into the tree, otherwise reinserts the original.
* @param event The mouse up event while using resize tool in proof mode
*/
export function proofResizeMouseUp(event: MouseEvent) {
if (legalNode) {
const moveDifference: Point = new Point(
Expand All @@ -96,6 +113,9 @@ export function proofResizeMouseUp(event: MouseEvent) {
}
}

/**
* If the mouse leaves the canvas then it is no longer a legal node and reinserts the original.
*/
export function proofResizeMouseOut() {
if (legalNode && currentNode !== null) {
currentProofTree.insert(currentNode);
Expand All @@ -104,6 +124,12 @@ export function proofResizeMouseOut() {
redrawTree(treeContext.getLastProofStep().tree);
}

/**
* Determines if a node in a given position is legal if it can be inserted, is bigger than our
* minimum ellipse radii size, and can be inserted into the tree without changing the structure.
* @param currentCut The cut to be checked to see if it is legal
* @returns Whether or not the cut in this position is legal
*/
function isLegal(currentCut: CutNode): boolean {
return (
currentProofTree.canInsert(currentCut) &&
Expand Down

0 comments on commit e2d9713

Please sign in to comment.