Интерактивный калькулятор площади треугольника
Расчётный алгоритм навеян из опытов в данной теме…
Использовался Калькулятор Площади Фигур для сверки расчётов… <html> <head> <title>Интерактивный калькулятор площади треугольника</title> <script> var Figure = { Ax: 0, Bx: 100, Cx: 65, Cy: 100, Dx: 25, Dy: NaN, Ex: 85, Ey: NaN }; var hOutputs = []; var hInputs = null; var hCanvas = null; function Calculate(fig, label) { var size_x = fig.Bx - fig.Ax; var size_y = fig.Cy; var width = pCanvas.canvas.width; var height = pCanvas.canvas.height; var font = pCanvas.font.match(/(\d+)px (.+)/); var fontHeight = parseInt(font[1]); var outputs = {}; var matrix = { a: (width - pCanvas.measureText("AxBx").width) / size_x, b: 0, c: 0, d: -(height - fontHeight * 2) / size_y, e: pCanvas.measureText("Ax").width, f: height - fontHeight }; function Text(txt, x, y, alignment) { [pCanvas.textAlign, pCanvas.textBaseline] = alignment.split(/\s+/); pCanvas.textAlign = alignment.split(/\s+/)[0]; pCanvas.textBaseline = alignment.split(/\s+/)[1]; pCanvas.fillStyle = txt == label ? "magenta" : "black"; pCanvas.fillText(txt, matrix.e + matrix.a * x, matrix.f + matrix.d * y); } function Line(txt, x1, y1, x2, y2) { pCanvas.beginPath(); pCanvas.setTransform(matrix); pCanvas.moveTo(x1, y1); pCanvas.lineTo(x2, y2) pCanvas.resetTransform(); pCanvas.strokeStyle = txt == label ? "magenta" : "blue"; pCanvas.lineWidth = txt == label ? 2 : 1; pCanvas.stroke(); } function Poly(txt, coords) { var first = true; if(txt != label) return; pCanvas.beginPath(); pCanvas.setTransform(matrix); while(coords.length > 0) { var x = coords.shift(); var y = coords.shift(); if(first) pCanvas.moveTo(x, y); else pCanvas.lineTo(x, y); first = false; } pCanvas.resetTransform(); pCanvas.fillStyle = "cyan"; pCanvas.closePath(); pCanvas.fill(); } fig.Dy = fig.Dx < fig.Cx ? (fig.Dx - fig.Ax) / (fig.Cx - fig.Ax) * fig.Cy : (fig.Bx - fig.Dx) / (fig.Bx - fig.Cx) * fig.Cy; fig.Ey = fig.Ex > fig.Cx ? (fig.Bx - fig.Ex) / (fig.Bx - fig.Cx) * fig.Cy : (fig.Ex - fig.Ax) / (fig.Cx - fig.Ax) * fig.Cy; if(fig.Ex < fig.Dx) { var tmp = fig.Dx; fig.Dx = fig.Ex; fig.Ex = tmp; } outputs = { Dy: fig.Dy, Ey: fig.Ey, ACy: Math.sqrt(Math.pow(fig.Cx - fig.Ax, 2) + Math.pow(fig.Cy, 2)), BCy: Math.sqrt(Math.pow(fig.Bx - fig.Cx, 2) + Math.pow(fig.Cy, 2)), ADy: fig.Dx < fig.Cx ? Math.sqrt(Math.pow(fig.Dx - fig.Ax, 2) + Math.pow(fig.Dy, 2)) : Math.sqrt(Math.pow(fig.Bx - fig.Dx, 2) + Math.pow(fig.Dy, 2)), BEy: fig.Ex > fig.Cx ? Math.sqrt(Math.pow(fig.Bx - fig.Ex, 2) + Math.pow(fig.Ey, 2)) : Math.sqrt(Math.pow(fig.Ex - fig.Ax, 2) + Math.pow(fig.Ey, 2)), ACxy: (fig.Cx - fig.Ax) * fig.Cy / 2, BCxy: (fig.Bx - fig.Cx) * fig.Cy / 2, ABCy: (fig.Ax + fig.Bx) * fig.Cy / 2, ADxy: fig.Dx > fig.Cx ? (fig.Bx - fig.Dx) * fig.Dy / 2 : (fig.Dx - fig.Ax) * fig.Dy / 2, BExy: fig.Ex < fig.Cx ? (fig.Ex - fig.Ax) * fig.Ey / 2 : (fig.Bx - fig.Ex) * fig.Ey / 2 }; outputs.DxyCxy = outputs.ACxy - outputs.ADxy; outputs.CxyExy = outputs.BCxy - outputs.BExy; outputs.DxyCyExy = fig.Ex < fig.Cx ? outputs.BExy - outputs.ADxy : fig.Dx > fig.Cx ? outputs.ADxy - outputs.BExy : outputs.DxyCxy + outputs.CxyExy; for(var id in outputs) hOutputs[id].textContent = outputs[id].toPrecision(8); pCanvas.setLineDash([]); pCanvas.fillStyle = "white"; pCanvas.fillRect(0, 0, width, height); Poly("ACxy", [fig.Ax, 0, fig.Cx, 0, fig.Cx, fig.Cy]); Poly("BCxy", [fig.Bx, 0, fig.Cx, 0, fig.Cx, fig.Cy]); Poly("ABCy", [fig.Ax, 0, fig.Bx, 0, fig.Cx, fig.Cy]); Poly("ADxy", [(fig.Dx < fig.Cx ? fig.Ax : fig.Bx), 0, fig.Dx, 0, fig.Dx, fig.Dy]); Poly("BExy", [(fig.Ex > fig.Cx ? fig.Bx : fig.Ax), 0, fig.Ex, 0, fig.Ex, fig.Ey]); Poly("DxyCxy", [fig.Dx, 0, fig.Dx, fig.Dy, fig.Cx, fig.Cy, fig.Cx, 0]); Poly("CxyExy", [fig.Cx, 0, fig.Cx, fig.Cy, fig.Ex, fig.Ey, fig.Ex, 0]); Poly("DxyCyExy", [fig.Dx, 0, fig.Dx, fig.Dy, fig.Cx, fig.Cy, fig.Ex, fig.Ey, fig.Ex, 0]); Text("Dy", fig.Dx, fig.Dy, fig.Dx < fig.Cx ? "right bottom" : "left bottom"); Text("Ey", fig.Ex, fig.Ey, fig.Ex > fig.Cx ? "left bottom" : "right bottom"); Text("Ax", fig.Ax, 0, "right top"); Text("Bx", fig.Bx, 0, "left top"); Text("Cx", fig.Cx, 0, "center top"); Text("Dx", fig.Dx, 0, "center top"); Text("Ex", fig.Ex, 0, "center top"); Text("Cy", fig.Cx, fig.Cy, "center bottom"); Line("", fig.Ax, 0, fig.Bx, 0); Line("ACy", fig.Ax, 0, fig.Cx, fig.Cy); Line("BCy", fig.Bx, 0, fig.Cx, fig.Cy); if(label == "ADy") Line(label, (fig.Dx < fig.Cx ? fig.Ax : fig.Bx), 0, fig.Dx, fig.Dy); if(label == "BEy") Line(label, (fig.Ex > fig.Cx ? fig.Bx : fig.Ax), 0, fig.Ex, fig.Ey); pCanvas.strokeStyle = "blue"; pCanvas.lineWidth = 1; pCanvas.setLineDash([2, 1]); pCanvas.beginPath(); pCanvas.setTransform(matrix); pCanvas.moveTo(fig.Cx, 0); pCanvas.lineTo(fig.Cx, fig.Cy); pCanvas.resetTransform(); pCanvas.stroke(); pCanvas.strokeStyle = "grey"; pCanvas.beginPath(); pCanvas.setTransform(matrix); pCanvas.moveTo(fig.Dx, 0); pCanvas.lineTo(fig.Dx, fig.Dy); pCanvas.moveTo(fig.Ex, 0); pCanvas.lineTo(fig.Ex, fig.Ey); pCanvas.resetTransform(); pCanvas.stroke(); } function main() { pCanvas = document.getElementById("Triangle").getContext("2d"); hInputs = document.querySelectorAll("input"); hInputs.forEach( function(el) { el.value = Figure[el.title]; if(el.readOnly) hOutputs[el.title] = el; el.addEventListener("change", function(evt) { var el = (evt || window.event).srcElement; Figure[el.title] = el.value; Calculate(Figure, el.title); } ); el.addEventListener("mouseover", function(evt) { var el = (evt || window.event).srcElement; Calculate(Figure, el.title); } ); el.addEventListener("mouseleave", function(evt) { Calculate(Figure); } ); } ); hCells = document.querySelectorAll("td[title]"); hCells.forEach( function(el) { hOutputs[el.title] = el; el.addEventListener("mouseover", function(evt) { var el = (evt || window.event).srcElement; Calculate(Figure, el.title); } ); el.addEventListener("mouseleave", function(evt) { Calculate(Figure); } ); } ); Calculate(Figure); } </script> </head> <body onload='main()' style=background-color:silver> <canvas id=Triangle width=640 height=200></canvas> <table><tr><td> <table border=1> <tr> <th></th><th>X</th><th>Y</th><th>Formula / Формула</th> </tr> <tr> <td>A</td> <td><input type=number min=0 max=0 value=0 title='Ax'></td> <td> </td> </tr> <tr> <td>B</td> <td><input type=number min=0 max=100 value=0 title='Bx'></td> <td> </td> </tr> <tr> <td>C</td> <td><input type=number min=0 max=100 value=0 title='Cx'></td> <td><input type=number min=0 max=100 value=0 title='Cy'></td> </tr> <td>D</td> <td><input type=number min=0 max=100 value=0 title='Dx'></td> <td title='Dy'></td> <td>= (Dx - Ax) / (Cx - Ax) * Cy</td> </tr> <td>E</td> <td><input type=number min=0 max=100 value=0 title='Ex'></td> <td title='Ey'></td> <td>= (Bx - Ex) / (Bx - Cx) * Cy</td> </tr> </table> </td> <td style=vertical-align:top><table border=1> <tr> <th></th><th>Length / Длина</th><th>Formula / Формула</th> </tr> <tr> <td>ACy</td> <td title='ACy'></td> <td>= √(ACx²+Cxy²)</td> </tr> <tr> <td>BCy</td> <td title='BCy'></td> <td>= √(BCx²+Cxy²)</td> </tr> <tr> <td>ADy</td> <td title='ADy'></td> <td>= √(ADx²+Dxy²)</td> </tr> <tr> <td>BEy</td> <td title='BEy'></td> <td>= √(BEx²+Exy²)</td> </tr> </table> </td></tr></table> <table border=1> <tr> <th>△</th><th>Area / Площадь</th><th>Formula / Формула</th> </tr> <tr> <td>ACxy</td> <td title='ACxy'></td> <td>= ACx * Cxy / 2</td> </tr> <tr> <td>BCxy</td> <td title='BCxy'></td> <td>= BCx * Cxy / 2</td> </tr> <tr> <td>ABCy</td> <td title='ABCy'></td> <td>= (ACx + BCx) * Cxy / 2</td> </tr> <tr> <td>ADxy</td> <td title='ADxy'></td> <td>= ADx * Dxy / 2</td> </tr> <tr> <td>DxyCxy</td> <td title='DxyCxy'></td></td> <td>= ACx * Cxy / 2 - ADx * Dxy / 2</td> </tr> <tr> <td>CxyExy</td> <td title='CxyExy'></td> <td>= BCx * Cxy / 2 - BEx * Exy / 2</td> </tr> <tr> <td>BExy</td> <td title='BExy'></td> <td>= BEx * Exy / 2</td> </tr> <tr> <td>DxyCyExy</td> <td title='DxyCyExy'></td> <td>= (ACx + BCx) * Cxy / 2 - BCx * Cxy / 2 - BEx * Exy / 2</td> </tr> </table> </body>Надеюс , кому-нибудь пригодится…:thanks: (Алгоритм насыщен простыми расчётными формулами, что может пригодиться новичкам в вычислительной геометрии.) P.S.: Заметили ошибку? Пишите - постараюсь исправить… |
Любить старину, конечно, можно. Но не до такой же степени.
el.addEventListener("mouseover", function(evt) { var el = (evt || window.event).srcElement; Calculate(Figure, el.title); } ); window.event был необходим только для IE8-. а mouseover и mouseleave появились только в IE9. Да и canvas в IE8 не было. |
Цитата:
Буду учитывать. А то с этой "обратной совместимостью" захламляется всё вдоль и поперёк… |
Часовой пояс GMT +3, время: 16:21. |