Skip to content

Commit

Permalink
Merge pull request #252 from RAIRLab/251-iteration-harder
Browse files Browse the repository at this point in the history
Working iteration I believe, no highlighting
  • Loading branch information
DawnTheWitch authored Nov 25, 2023
2 parents 13f622c + 3eb4153 commit 25b9d5c
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/DrawModes/DrawUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,6 @@ function redrawCut(incomingNode: CutNode) {
* @param incomingNode The Atom Node to be redrawn
* @param offset The difference between the actual graph and the current canvas
*/
function redrawAtom(incomingNode: AtomNode) {
export function redrawAtom(incomingNode: AtomNode) {
drawAtom(incomingNode, placedColor(), false);
}
161 changes: 161 additions & 0 deletions src/ProofTools/IterationTool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/**
* A tool used to iterated subgraphs on the AEG
* @author
*/

import {Point} from "../AEG/Point";
import {Ellipse} from "../AEG/Ellipse";
import {AtomNode} from "../AEG/AtomNode";
import {CutNode} from "../AEG/CutNode";
import {treeContext} from "../treeContext";
import {offset} from "../DrawModes/DragTool";
import {drawAtom, redrawTree} from "../DrawModes/DrawUtils";
import {legalColor, illegalColor} from "../Themes";
import {
validateChildren,
drawAltered,
insertChildren,
alterAtom,
alterCut,
} from "../DrawModes/EditModeUtils";

//The initial point the user pressed down.
let startingPoint: Point;

//The current node and its children we will be moving.
let currentNode: CutNode | AtomNode | null = null;

//The parent of the currentNode.
let currentParent: CutNode | null = null;

//Whether or not the node is allowed to be moved (not the sheet).
let legalNode: boolean;

/**
* Sets the starting point for future use as well as obtaining the lowest node containing this point.
* Also obtains the parent of this lowest point for future use as well.
* @param event The mouse down event while using the iteration tool
*/
export function iterationMouseDown(event: MouseEvent) {
startingPoint = new Point(event.x - offset.x, event.y - offset.y);
currentNode = treeContext.tree.getLowestNode(startingPoint);
currentParent = treeContext.tree.getLowestParent(startingPoint);

//So long as we have obtained a node that isn't the sheet we are allowed to select this.
legalNode = currentNode !== treeContext.tree.sheet && currentNode !== null;
}

/**
* If we have selected a legal node then determines how far it has moved from the original node.
* If it is a cut node determines if this new position is legal for all of its children and draws
* that in its correct color. If it's an atom it just checks to see if that is in the correct position.
* @param event The mouse move event while using the iteration tool
*/
export function iterationMouseMove(event: MouseEvent) {
if (legalNode) {
const moveDifference: Point = new Point(
event.x - startingPoint.x,
event.y - startingPoint.y
);

redrawTree(treeContext.tree);
const currentPoint = new Point(event.x - offset.x, event.y - offset.y);
const color = isLegal(moveDifference, currentPoint) ? legalColor() : illegalColor();
if (currentNode instanceof CutNode) {
drawAltered(currentNode, color, moveDifference);
} else if (currentNode instanceof AtomNode) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);
drawAtom(tempAtom, color, true);
}
}
}

/**
* Checks to see if the node and any of its children are illegal in the new position. If any are
* illegal does not insert any of them. Redraws the canvas to update this.
* @param event The mouse out event while using the iteration tool
*/
export function iterationMouseUp(event: MouseEvent) {
if (legalNode) {
const moveDifference: Point = new Point(
event.x - startingPoint.x,
event.y - startingPoint.y
);

if (isLegal(moveDifference, new Point(event.x - offset.x, event.y - offset.y))) {
if (currentNode instanceof CutNode) {
insertChildren(currentNode, moveDifference);
} else if (currentNode instanceof AtomNode) {
const tempAtom: AtomNode = alterAtom(currentNode, moveDifference);
treeContext.tree.insert(tempAtom);
}
}
}
redrawTree(treeContext.tree);
legalNode = false;
}

/**
* If the mouse has left the canvas then assume it is now illegal and reset the tree.
*/
export function iterationMouseOut() {
legalNode = false;
redrawTree(treeContext.tree);
}

/**
* If the current point is legally iterated (within the parent of the original node)
* checks if the altered nodes can be inserted, if all of them can returns true.
* @param moveDifference The change from the currentNodes original position
* @param currentPoint The current point on the graph the mouse is
* @returns Whether or not this location is legal
*/
function isLegal(moveDifference: Point, currentPoint: Point): boolean {
//If the current parent exists and contains our current point then checks whether the node
//Is an atom or cut for their own individual legality check.
return (
currentParent !== null &&
currentParent.containsPoint(currentPoint) &&
//If the currentNode is a cut, then it is legal if it and all if it's children can be placed
//legally, and if the node we have selected can not be inserted over something else.
((currentNode instanceof CutNode &&
validateChildren(currentNode, moveDifference) &&
insertChildless(
treeContext.tree.sheet,
alterCut(currentNode, moveDifference).ellipse!
)) ||
//AtomNodes are legal if they can be inserted in their current location.
(currentNode instanceof AtomNode &&
treeContext.tree.canInsert(alterAtom(currentNode, moveDifference))))
);
}

/**
* Determines if the current location and shape of the ellipse would have any children in
* it's current position, acts recursively for cut nodes starting with the sheet.
* @param currentNode The current node we are checking in the recursive function starting with the sheet
* @param currentEllipse The ellipse of the altered cut node we are trying to place
* @returns Whether or not the node would have any children
*/
function insertChildless(currentNode: CutNode, currentEllipse: Ellipse): boolean {
for (let i = 0; i < currentNode.children.length; i++) {
if (currentNode.children[i] instanceof CutNode) {
//So long as the ellipse is not null, and either our current cut or any of it's
//Children have a child that is contained by our ellipse then it is false
if (
(currentNode.children[i] as CutNode).ellipse instanceof Ellipse &&
(currentEllipse.contains((currentNode.children[i] as CutNode).ellipse!) ||
!insertChildless(currentNode.children[i] as CutNode, currentEllipse))
) {
return false;
}
} else if (
currentNode.children[i] instanceof AtomNode &&
currentEllipse.contains((currentNode.children[i] as AtomNode).calcRect())
) {
return false;
}
}

return true;
}
6 changes: 3 additions & 3 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@
</button>
</div>
<div class="row">
<button type="button" onclick="" title="Iteration" class="toolButton">
<i class="fa fa-circle-o" aria-hidden="true"></i>
<button type="button" onclick="setTool(iterationTool)" title="Iteration" class="toolButton">
<i class="fa fa-expand" aria-hidden="true"></i>
</button>
<button type="button" onclick="" title="Deiteration" class="toolButton">
<i class="fa fa-circle-o" aria-hidden="true"></i>
<i class="fa fa-compress" aria-hidden="true"></i>
</button>
</div>
</div>
Expand Down
21 changes: 20 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,18 @@ import {
erasureMouseOut,
} from "./ProofTools/ErasureTool";
import {toggleHandler} from "./ToggleModes";

import {
resizeMouseDown,
resizeMouseMove,
resizeMouseUp,
resizeMouseOut,
} from "./DrawModes/ResizeTool";
import {
iterationMouseDown,
iterationMouseMove,
iterationMouseUp,
iterationMouseOut,
} from "./ProofTools/IterationTool";

//Setting up Canvas
const canvas: HTMLCanvasElement = <HTMLCanvasElement>document.getElementById("canvas");
Expand Down Expand Up @@ -132,6 +137,7 @@ window.doubleCutInsertionTool = Tool.doubleCutInsertionTool;
window.resizeTool = Tool.resizeTool;
window.doubleCutDeletionTool = Tool.doubleCutDeletionTool;
window.erasureTool = Tool.erasureTool;
window.iterationTool = Tool.iterationTool;
window.setTool = setTool;
window.setHighlight = setHighlight;
window.toggleHandler = toggleHandler;
Expand All @@ -154,6 +160,7 @@ declare global {
doubleCutInsertionTool: Tool;
doubleCutDeletionTool: Tool;
erasureTool: Tool;
iterationTool: Tool;
setTool: (state: Tool) => void;
setHighlight: (event: string, id: string) => void;
toggleHandler: () => void;
Expand Down Expand Up @@ -331,6 +338,9 @@ function mouseDownHandler(event: MouseEvent) {
case Tool.erasureTool:
erasureMouseDown(event);
break;
case Tool.iterationTool:
iterationMouseDown(event);
break;
default:
break;
}
Expand Down Expand Up @@ -386,6 +396,9 @@ function mouseMoveHandler(event: MouseEvent) {
case Tool.erasureTool:
erasureMouseMove(event);
break;
case Tool.iterationTool:
iterationMouseMove(event);
break;
default:
break;
}
Expand Down Expand Up @@ -438,6 +451,9 @@ function mouseUpHandler(event: MouseEvent) {
case Tool.erasureTool:
erasureMouseUp(event);
break;
case Tool.iterationTool:
iterationMouseUp(event);
break;
default:
break;
}
Expand Down Expand Up @@ -492,6 +508,9 @@ function mouseOutHandler() {
case Tool.erasureTool:
erasureMouseOut();
break;
case Tool.iterationTool:
iterationMouseOut();
break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/treeContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum Tool {
doubleCutInsertionTool,
doubleCutDeletionTool,
erasureTool,
iterationTool,
}

export class treeContext {
Expand Down

0 comments on commit 25b9d5c

Please sign in to comment.