Расчётный алгоритм навеян из опытов в
данной теме…
Использовался
Калькулятор Площади Фигур для сверки расчётов…
<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>
Надеюс , кому-нибудь пригодится…
(Алгоритм насыщен простыми расчётными формулами, что может пригодиться новичкам в вычислительной геометрии.)
P.S.: Заметили ошибку?
Пишите - постараюсь исправить…