Skip to content

Commit be9ea0f

Browse files
authored
Merge pull request #1195 from drgrice1/graphtool-vector
Add a vector tool to the graph tool.
2 parents c50623b + 131c21f commit be9ea0f

File tree

5 files changed

+402
-13
lines changed

5 files changed

+402
-13
lines changed

htdocs/js/GraphTool/graphtool.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@
243243
&.gt-quadrilateral-tool {
244244
background-image: url('images/Quadrilateral.svg');
245245
}
246+
247+
&.gt-segment-tool {
248+
background-image: url('images/Segment.svg');
249+
}
250+
251+
&.gt-vector-tool {
252+
background-image: url('images/Vector.svg');
253+
}
246254
}
247255
}
248256

Lines changed: 8 additions & 0 deletions
Loading
Lines changed: 8 additions & 0 deletions
Loading

htdocs/js/GraphTool/segments.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/* global graphTool, JXG */
2+
3+
'use strict';
4+
5+
(() => {
6+
if (!graphTool) return;
7+
8+
const stringify = function (gt) {
9+
return [
10+
this.baseObj.getAttribute('dash') === 0 ? 'solid' : 'dashed',
11+
...this.definingPts.map(
12+
(point) => `(${gt.snapRound(point.X(), gt.snapSizeX)},${gt.snapRound(point.Y(), gt.snapSizeY)})`
13+
)
14+
].join(',');
15+
};
16+
17+
const restore = function (gt, string, objectClass) {
18+
let pointData = gt.pointRegexp.exec(string);
19+
const points = [];
20+
while (pointData) {
21+
points.push(pointData.slice(1, 3));
22+
pointData = gt.pointRegexp.exec(string);
23+
}
24+
if (points.length < 2) return false;
25+
const point1 = gt.createPoint(parseFloat(points[0][0]), parseFloat(points[0][1]));
26+
const point2 = gt.createPoint(parseFloat(points[1][0]), parseFloat(points[1][1]), point1);
27+
return new objectClass(point1, point2, /solid/.test(string));
28+
};
29+
30+
const initialize = function (gt, helpText, objectClass) {
31+
this.phase1 = (coords) => {
32+
gt.toolTypes.LineTool.prototype.phase1.call(this, coords);
33+
this.helpText = helpText;
34+
gt.updateHelp();
35+
};
36+
37+
this.phase2 = (coords) => {
38+
if (!gt.boardHasPoint(coords[1], coords[2])) return;
39+
40+
// If the current coordinates are on top of the first,
41+
// then use the highlight point coordinates instead.
42+
if (
43+
Math.abs(this.point1.X() - gt.snapRound(coords[1], gt.snapSizeX)) < JXG.Math.eps &&
44+
Math.abs(this.point1.Y() - gt.snapRound(coords[2], gt.snapSizeY)) < JXG.Math.eps
45+
)
46+
coords = this.hlObjs.hl_point.coords.usrCoords;
47+
48+
gt.board.off('up');
49+
50+
const point1 = this.point1;
51+
delete this.point1;
52+
53+
point1.setAttribute(gt.definingPointAttributes);
54+
55+
point1.on('down', () => gt.onPointDown(point1));
56+
point1.on('up', () => gt.onPointUp(point1));
57+
58+
const point2 = gt.createPoint(coords[1], coords[2], point1);
59+
gt.selectedObj = new objectClass(point1, point2, gt.drawSolid);
60+
gt.selectedObj.focusPoint = point2;
61+
gt.graphedObjs.push(gt.selectedObj);
62+
63+
this.finish();
64+
};
65+
};
66+
67+
if (!graphTool.segmentTool) {
68+
graphTool.segmentTool = {
69+
Segment: {
70+
parent: 'line',
71+
72+
postInit(_gt, _point1, _point2, _solid) {
73+
this.baseObj.setAttribute({ straightFirst: false, straightLast: false });
74+
},
75+
76+
stringify(gt) {
77+
return stringify.call(this, gt);
78+
},
79+
80+
restore(gt, string) {
81+
return restore.call(this, gt, string, gt.graphObjectTypes.segment);
82+
}
83+
},
84+
85+
SegmentTool: {
86+
iconName: 'segment',
87+
tooltip: 'Segment Tool: Graph a line segment.',
88+
parent: 'LineTool',
89+
90+
initialize(gt) {
91+
initialize.call(this, gt, 'Plot the other end of the line segment.', gt.graphObjectTypes.segment);
92+
},
93+
94+
updateHighlights(gt, e) {
95+
const handled = gt.toolTypes.LineTool.prototype.updateHighlights.call(this, e);
96+
this.hlObjs.hl_line?.setAttribute({ straightFirst: false, straightLast: false });
97+
return handled;
98+
},
99+
100+
activate(gt) {
101+
this.helpText = 'Plot the points at the ends of the line segment.';
102+
gt.updateHelp();
103+
}
104+
}
105+
};
106+
}
107+
108+
if (!graphTool.vectorTool) {
109+
graphTool.vectorTool = {
110+
Vector: {
111+
parent: 'line',
112+
113+
postInit(_gt, _point1, _point2, _solid) {
114+
this.baseObj.setAttribute({ straightFirst: false, straightLast: false });
115+
this.baseObj.setArrow(false, { type: 1, size: 4 });
116+
},
117+
118+
stringify(gt) {
119+
return stringify.call(this, gt);
120+
},
121+
122+
restore(gt, string) {
123+
return restore.call(this, gt, string, gt.graphObjectTypes.vector);
124+
}
125+
},
126+
127+
VectorTool: {
128+
iconName: 'vector',
129+
tooltip: 'Vector Tool: Graph a vector.',
130+
parent: 'LineTool',
131+
132+
initialize(gt) {
133+
initialize.call(this, gt, 'Plot the terminal point of the vector.', gt.graphObjectTypes.vector);
134+
},
135+
136+
updateHighlights(gt, e) {
137+
const handled = gt.toolTypes.LineTool.prototype.updateHighlights.call(this, e);
138+
this.hlObjs.hl_line?.setAttribute({
139+
straightFirst: false,
140+
straightLast: false,
141+
lastArrow: { type: 1, size: 6 }
142+
});
143+
return handled;
144+
},
145+
146+
activate(gt) {
147+
this.helpText = 'Plot the initial point and then the terminal point of the vector.';
148+
gt.updateHelp();
149+
}
150+
}
151+
};
152+
}
153+
})();

0 commit comments

Comments
 (0)