我有this jsbin显示我的工作。
在jsbin中,我试图通过与A线垂直的点A(1,1)绘制一条直线,该线具有B(6,18)和C(14,16)点。
我解决这个问题的方法是尝试将2个方程式转换为y = mx + c
形式,然后将它们重新排列为y -mx = c
,然后使用矩阵通过联立方程求解它们。
我有这个高度函数来完成工作:
function altitude(vertex, a, b) {
var slope = gradient(a, b),
x1 = - slope,
y1 = 1,
c1 = getYIntercept(a, slope),
perpendicularSlope = perpendicularGradient(a, b),
x2 = - perpendicularSlope,
y2 = 1,
c2 = getYIntercept(vertex, perpendicularSlope);
var matrix = [
[x1, y1],
[x2, y2]
];
var result = solve(matrix, [c1, c2]);
var g = svg.append('g');
g.append('line')
.style('stroke', 'red')
.attr('class', 'line')
.attr('x1', xScale(vertex.x))
.attr('y1', yScale(vertex.y))
.attr('x2', xScale(result.x))
.attr('y2', yScale(result.y));
}
我首先使用此函数获取BC的渐变
var gradient = function(a, b) {
return (b.y - a.y) / (b.x - a.x);
};
这是-1.5,从中我可以使用此函数得到垂直渐变:
var perpendicularGradient = function (a, b) {
return -1 / gradient(a, b);
};
我将其设为0.66666或(2/3)。
我将2个方程看起来像这样:
y + 1.5 = 27
y -0.6666666666666666 = 0.33333333333333337
我在jsbin中有一些函数可以使用矩阵和Cramer的规则同时解决这些问题,主要解决这个问题:
function solve(matrix, r) {
var determinant = det(matrix);
var x = det([
[r[0], matrix[0][1]],
[r[1], matrix[1][1]]
]) / determinant;
var y = det([
[matrix[0][0], r[0]],
[matrix[1][0], r[1]]
]) / determinant;
return {x: Math.approx(x), y: Math.approx(y)};
}
function det(matrix) {
return (matrix[0][0]*matrix[1][1])-(matrix[0][1]*matrix[1][0]);
}
我得到拦截的坐标大致为(12.31,8.54)。
问题是,它在图表上看起来并不正确。
我在某个地方采取了错误的步骤吗?我认为我的计算是正确的,但我不排除它们是错的。它可能会缩小规模。
答案 0 :(得分:2)
您想要找到A点到线BC的投影。
让我们制作向量
问 = C - B
P = A - B
标准化(单位长度):
uQ = 问 / | 问 |
需要的投影点 D 是
D = B + uQ * DotProduct( P , uQ )
对于您的示例A(1,1),B(6,18),C(14,6)
Q =(8,-12)
| 问强> | = Sqrt(8 * 8 + 12 * 12)~14.4
uQ =(0.55,-0.83)
的 P 强> =( - 5,-17)
DotProduct( P , uQ )= 0.55 *( - 5) - (0.83 * -17)= 11.39
D =(6 + 0.55 * 11.39,18-0.83 * 11.39)=(12.26,8,54)
所以你的计算给出了正确的结果(虽然方法不是很有效),但是图片并不精确 - 不同比例的X和Y轴变形角度。
P.S:第二行width = 660 - margin.left - margin.right,
使图片更可靠