使用 d3 检查三角形高度的逻辑
Check logic for altitude of a triangle using d3
我有 this jsbin 显示我的工作。
在 jsbin 中,我试图通过点 A (1, 1) 绘制一条垂直于线 BC 的高度线,线 BC 具有点 B (6, 18) 和 C (14, 6)。
我解决这个问题的方法是尝试将 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 中有一些函数可以使用矩阵和克拉默规则同时解决这些问题,主要的是解决:
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)。
问题是,它在图表上看起来不正确。
我是不是哪里走错了?我认为我的计算是正确的,但我不排除它们是错误的。它可能会缩小规模。
你想求A点在BC线上的投影。
让我们制作矢量
Q = C - B
P = A - B
归一化(单位长度):
uQ = Q/ |Q|
需要的投影点D是
D = B + uQ * 点积(P, uQ)
对于你的例子 A(1,1), B(6,18), C(14,6)
Q = (8, -12)
|Q| = Sqrt(8*8+12*12)~14.4
uQ= (0.55, -0.83)
P=(-5,-17)
点积(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,
让图片更靠谱
我有 this jsbin 显示我的工作。
在 jsbin 中,我试图通过点 A (1, 1) 绘制一条垂直于线 BC 的高度线,线 BC 具有点 B (6, 18) 和 C (14, 6)。
我解决这个问题的方法是尝试将 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 中有一些函数可以使用矩阵和克拉默规则同时解决这些问题,主要的是解决:
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)。
问题是,它在图表上看起来不正确。
我是不是哪里走错了?我认为我的计算是正确的,但我不排除它们是错误的。它可能会缩小规模。
你想求A点在BC线上的投影。
让我们制作矢量
Q = C - B
P = A - B
归一化(单位长度):
uQ = Q/ |Q|
需要的投影点D是
D = B + uQ * 点积(P, uQ)
对于你的例子 A(1,1), B(6,18), C(14,6)
Q = (8, -12)
|Q| = Sqrt(8*8+12*12)~14.4
uQ= (0.55, -0.83)
P=(-5,-17)
点积(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,
让图片更靠谱