<iframe src="https://jsxgraph.org/share/iframe/arrows-for-technical-drawings" style="border: 1px solid black; overflow: hidden; width: 550px; aspect-ratio: 55 / 65;" name="JSXGraph example: Arrows for technical drawings" allowfullscreen ></iframe>
<div id="board-0-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-0" class="jxgbox" style="aspect-ratio: 12 / 10; width: 100%;" data-ar="12 / 10"></div> </div> <textarea id="output" cols="70" rows="20"></textarea> <script type = "text/javascript"> /* This example is licensed under a Creative Commons Attribution 4.0 International License. https://creativecommons.org/licenses/by/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'board-0'; const board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-8, 7, 4, -3], axis: true }); var l = 5, insetRatio, tipAngle, wingCurve, tailCurve; insetRatio = board.create('slider', [[-6, 5.5], [0, 5.5], [0, 1, 2]], {name: 'inset ratio', snapWidth: 0.1}); tipAngle = board.create('slider', [[-6, 5], [0, 5], [0, 30, 90]], {name: 'tip angle', snapWidth: 1}); wingCurve = board.create('slider', [[-6, 4.5], [0, 4.5], [0, 0, 30]], {name: 'wing curve', snapWidth: 1}); tailCurve = board.create('slider', [[-6, 4], [0, 4], [0, 0, 40]], {name: 'tail curve', snapWidth: 1}); var arrowhead = board.create('curve', [[], []], {strokeColor: 'blue', strokeOpacity: 0.4, fillColor: 'blue', fillOpacity: 0.4, strokeWidth: 10, lineCap: 'square'}); arrowhead.updateDataArray = function() { var p = [], p2, f, ang, res, ang1, ang2, arr = [], arr2 = [], controls, ir = insetRatio.Value(), ta = tipAngle.Value(), wc = wingCurve.Value(), tc = tailCurve.Value(); p.push([0, 0]); ang = 0.5 * ta * Math.PI / 180; p.push([-l / ir, l * Math.sin(ang) / Math.cos(ang)]); p.push([-l, 0]); p.push([p[1][0], -p[1][1]]); ang1 = Math.atan2(p[2][1] - p[1][1], p[2][0] - p[1][0]) * 180 / Math.PI + tc; if (tc === 0) { ang2 = [ang1, 180 - ang1]; } else { ang2 = -90; } controls = { tension: 1, 0: {direction: [0.5 * ta - wc, 180 - 0.5 * ta + wc]}, 1: {direction: [180 - 0.5 * ta - wc, ang1]}, 2: {direction: ang2}, 3: {direction: [180 - ang1, 0.5 * ta + wc]}, isClosed: true }; res = JXG.Math.Metapost.curve(p, controls); this.bezierDegree = 3; this.dataX = res[0]; this.dataY = res[1]; f = 10 / (p[0][0] - p[1][0]); p2 = p.map( z => [f * (z[0] - p[3][0]), f * (z[1] - p[3][1])] ); res = JXG.Math.Metapost.curve(p2, controls); arr = res[0].map( (x, i) => [x.toFixed(2) + ',' + res[1][i].toFixed(2)] ); arr2 = res[0].map( (x, i) => [(10-x).toFixed(2) + ',' + res[1][i].toFixed(2)] ); document.getElementById('output').value = 'insetRatio:' + ir + ' ' + 'tipAngle:' + ta + ' ' + 'wingCurve:' + wc + ' ' + 'tailCurve:' + tc + '\n\n' + arr.join(' C ') + '\n\n' + arr2.join(' C '); }; var li = board.create('segment', [[-10, 0], [0,0]], {strokeWidth: 10, strokeOpacity: 0.4}); board.update(); </script>
/* This example is licensed under a Creative Commons Attribution 4.0 International License. https://creativecommons.org/licenses/by/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'your_div_id'; // Insert your id here! const board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-8, 7, 4, -3], axis: true }); var l = 5, insetRatio, tipAngle, wingCurve, tailCurve; insetRatio = board.create('slider', [[-6, 5.5], [0, 5.5], [0, 1, 2]], {name: 'inset ratio', snapWidth: 0.1}); tipAngle = board.create('slider', [[-6, 5], [0, 5], [0, 30, 90]], {name: 'tip angle', snapWidth: 1}); wingCurve = board.create('slider', [[-6, 4.5], [0, 4.5], [0, 0, 30]], {name: 'wing curve', snapWidth: 1}); tailCurve = board.create('slider', [[-6, 4], [0, 4], [0, 0, 40]], {name: 'tail curve', snapWidth: 1}); var arrowhead = board.create('curve', [[], []], {strokeColor: 'blue', strokeOpacity: 0.4, fillColor: 'blue', fillOpacity: 0.4, strokeWidth: 10, lineCap: 'square'}); arrowhead.updateDataArray = function() { var p = [], p2, f, ang, res, ang1, ang2, arr = [], arr2 = [], controls, ir = insetRatio.Value(), ta = tipAngle.Value(), wc = wingCurve.Value(), tc = tailCurve.Value(); p.push([0, 0]); ang = 0.5 * ta * Math.PI / 180; p.push([-l / ir, l * Math.sin(ang) / Math.cos(ang)]); p.push([-l, 0]); p.push([p[1][0], -p[1][1]]); ang1 = Math.atan2(p[2][1] - p[1][1], p[2][0] - p[1][0]) * 180 / Math.PI + tc; if (tc === 0) { ang2 = [ang1, 180 - ang1]; } else { ang2 = -90; } controls = { tension: 1, 0: {direction: [0.5 * ta - wc, 180 - 0.5 * ta + wc]}, 1: {direction: [180 - 0.5 * ta - wc, ang1]}, 2: {direction: ang2}, 3: {direction: [180 - ang1, 0.5 * ta + wc]}, isClosed: true }; res = JXG.Math.Metapost.curve(p, controls); this.bezierDegree = 3; this.dataX = res[0]; this.dataY = res[1]; f = 10 / (p[0][0] - p[1][0]); p2 = p.map( z => [f * (z[0] - p[3][0]), f * (z[1] - p[3][1])] ); res = JXG.Math.Metapost.curve(p2, controls); arr = res[0].map( (x, i) => [x.toFixed(2) + ',' + res[1][i].toFixed(2)] ); arr2 = res[0].map( (x, i) => [(10-x).toFixed(2) + ',' + res[1][i].toFixed(2)] ); document.getElementById('output').value = 'insetRatio:' + ir + ' ' + 'tipAngle:' + ta + ' ' + 'wingCurve:' + wc + ' ' + 'tailCurve:' + tc + '\n\n' + arr.join(' C ') + '\n\n' + arr2.join(' C '); }; var li = board.create('segment', [[-10, 0], [0,0]], {strokeWidth: 10, strokeOpacity: 0.4}); board.update();
// Define the id of your board in BOARDID const board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-8, 7, 4, -3], axis: true }); var l = 5, insetRatio, tipAngle, wingCurve, tailCurve; insetRatio = board.create('slider', [[-6, 5.5], [0, 5.5], [0, 1, 2]], {name: 'inset ratio', snapWidth: 0.1}); tipAngle = board.create('slider', [[-6, 5], [0, 5], [0, 30, 90]], {name: 'tip angle', snapWidth: 1}); wingCurve = board.create('slider', [[-6, 4.5], [0, 4.5], [0, 0, 30]], {name: 'wing curve', snapWidth: 1}); tailCurve = board.create('slider', [[-6, 4], [0, 4], [0, 0, 40]], {name: 'tail curve', snapWidth: 1}); var arrowhead = board.create('curve', [[], []], {strokeColor: 'blue', strokeOpacity: 0.4, fillColor: 'blue', fillOpacity: 0.4, strokeWidth: 10, lineCap: 'square'}); arrowhead.updateDataArray = function() { var p = [], p2, f, ang, res, ang1, ang2, arr = [], arr2 = [], controls, ir = insetRatio.Value(), ta = tipAngle.Value(), wc = wingCurve.Value(), tc = tailCurve.Value(); p.push([0, 0]); ang = 0.5 * ta * Math.PI / 180; p.push([-l / ir, l * Math.sin(ang) / Math.cos(ang)]); p.push([-l, 0]); p.push([p[1][0], -p[1][1]]); ang1 = Math.atan2(p[2][1] - p[1][1], p[2][0] - p[1][0]) * 180 / Math.PI + tc; if (tc === 0) { ang2 = [ang1, 180 - ang1]; } else { ang2 = -90; } controls = { tension: 1, 0: {direction: [0.5 * ta - wc, 180 - 0.5 * ta + wc]}, 1: {direction: [180 - 0.5 * ta - wc, ang1]}, 2: {direction: ang2}, 3: {direction: [180 - ang1, 0.5 * ta + wc]}, isClosed: true }; res = JXG.Math.Metapost.curve(p, controls); this.bezierDegree = 3; this.dataX = res[0]; this.dataY = res[1]; f = 10 / (p[0][0] - p[1][0]); p2 = p.map( z => [f * (z[0] - p[3][0]), f * (z[1] - p[3][1])] ); res = JXG.Math.Metapost.curve(p2, controls); arr = res[0].map( (x, i) => [x.toFixed(2) + ',' + res[1][i].toFixed(2)] ); arr2 = res[0].map( (x, i) => [(10-x).toFixed(2) + ',' + res[1][i].toFixed(2)] ); document.getElementById('output').value = 'insetRatio:' + ir + ' ' + 'tipAngle:' + ta + ' ' + 'wingCurve:' + wc + ' ' + 'tailCurve:' + tc + '\n\n' + arr.join(' C ') + '\n\n' + arr2.join(' C '); }; var li = board.create('segment', [[-10, 0], [0,0]], {strokeWidth: 10, strokeOpacity: 0.4}); board.update();
<textarea id="output" cols="70" rows="20"></textarea>
This example is licensed under a Creative Commons Attribution 4.0 International License. Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits.