我需要从一条线段中绘制一个三角形-如何找到中心点?

3
在我的JavaScript应用程序中,我有一个线段 - 基本上是画布上的两个已知点。我需要动态绘制一个钝角等腰三角形,其中最长的线是这两个点,而两条匹配的线是从中心点到边缘。
所以我想问的问题是,如何找到任意两个给定点之间的中心点?
我对JavaScript还算熟悉,但对数学不太了解。我能找到的每一个现实世界的答案都提到了一个指南针,但我不确定它如何转换成代码?我可以画出这些线,只是找不到那个点。感谢您的帮助!

您需要至少一个角度才能实现这一点。 - undefined
首先,在线段上找到中心点(简单的代数运算),然后找到一条垂直于原始线段且经过该点的线(同样是简单的代数运算)。在这条线上选择任意一点。这将构成你的三角形。 - undefined
@Hogan 没有任何意义。OP特别要求一个钝角等腰三角形。 - undefined
请注意,我刚刚看到了"OBTUSE"这个词。对于这个问题,你需要确保从第一个点到新点的距离小于原始线段的1/2。 - undefined
@Zéychin - 是的,我看到了,然后在我还没来得及发布上面的内容之前,我就被从办公桌上叫走了。 - undefined
2个回答

2
让我们尝试更简单的方法,只使用线性代数和几何学。
生成等腰三角形
你要找的点与你已经有的两个点等距离(这就是“等腰”的含义)。因此它在平分线上(垂直于线段并将其分为两个相等部分的线)drawing of obtuse isosceles triangle (来源:free.fr 一条线段[BC]的正交向量u( -(c.y-b.y), c.x-b.x ),因此所有形如A = I + t * u的点,其中t是任意标量(也就是数字),与BC组成一个等腰三角形。
为了构建这个向量u,我们取向量B到C的方向,即(c.x-b.x, c.y-b.y),我们知道对于任何向量(x,y),向量(-y,x)都垂直于它:尝试用它们两个做标量积。
I的坐标很简单:B和C的平均值(实际上是重心)( (b.x + c.x)/2, (b.y + c.y)/2 )

让它们变钝

为了使角度变钝,距离ABAC(相同)必须小于使A处的角度为90°的值。
当 A 点的角度为 90° 时,我们需要观察三角形 AIC。它在 A 点的角度为 90°/2=45°,由于它在 I 点的角度为 90°,且三角形内角和始终为 180°,因此 AIC 在 C 点的角度也是 45°。两个相等的角度就像两个相等的边一样,是等腰三角形的特征。
因此,AI = IC,由于 IC = BC / 2,所以 AI 的极限值为 BC / 2。
现在,我们必须选择一个 t,使得 AI < BC / 2,其中 AI = abs(t) * |u|。
让我们记住,我们没有对向量 u 进行归一化处理,因此 |u| = sqrt((-c.y+b.y)^2 + (c.x-b.x)^2),我们还有 BC = sqrt((b.x-c.x)^2 + (c.y-b.y)^2),因此 |u| = BC。
因此,我们可以得出结论:abs(t) < BC / (2 * |u|) = 1/2
最终算法:尽可能简单
  • [-0.5,0][0,0.5]之间选择一个t,不包括边界。
  • a.x = (b.x-c.x)/2 - t*(c.y-b.y)
  • a.y = (b.y+c.y)/2 + t*(c.x-b.x)
最后但并非最不重要的是,试一试它:

function draw()
{
    var t = parseFloat(document.getElementById('t').value);
      
    a.x = (b.x+c.x)/2 - t*(c.y-b.y);
    a.y = (b.y+c.y)/2 + t* (c.x-b.x);

    // end of the math, do the drawing
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.moveTo(a.x,a.y);
    ctx.lineTo(b.x,b.y);
    ctx.lineTo(c.x,c.y);
    ctx.closePath();
    ctx.stroke();
}

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

var b = {x:420, y:190}, c = {x:50, y:160}, a = {x:0, y:0};

ctx.fillRect(b.x,b.y,2,2);
ctx.fillRect(c.x,c.y,2,2);

document.getElementById('t').onchange = draw;
draw();
<p>t=<input type="text" id ="t" value="0.2" /></p>
<canvas id="c" width="500" height="300" />


1
线性代数使理解变得有些困难,但是推导a.xa.y的解释和最终简洁性非常出色。这应该是被接受的答案。 - undefined

1

大部分情况下,在2D坐标系中,这一切都可以通过基本的代数运算完成。您需要确定原始线的中心点和斜率,从这两个信息中,您可以轻松绘制垂直点。

查找中心点

要找到两个点之间的中心点,您应该能够获取相应x和y坐标之间的差异并除以二,然后将其加到起始值中:

function getCenterPoint(a, b) {
    return { x: (b.x - a.x) / 2 + a.x, y: (b.y - a.y) / 2 + a.y }; 
}

var p1 = { x: 10, y: 10 }
var p2 = { x: 90, y: 40 }
var center = getCenterPoint(pt1, pt2); // { x: 50, y: 25 }

寻找斜率

你可以通过上升与下降的比例来计算线段的斜率:

function getSlope(a, b) {
    return (b.y - a.y) / (b.x - a.x);
}

var slope = getSlope(p1, p2);

为了获得垂直斜率,您可以将其取反并倒置:
var perpendicularSlope = -(1 / slope);

使用斜率绘制点

现在您可以在垂直于中心点的线上绘制任何点。在您的示例中,要上升到您的直线上,您需要使用一个比中心点小的x值,要下降到您的直线下方,您需要使用比中心点大的x值。要确定y值,您需要将斜率乘以x值。

var pAbove = { x: center.x - 10, y: (center.x - 10) * perpendicularSlope };
var pBelow = { x: center.x + 10, y: (center.x + 10) * perpendicularSlope };

现在来说垂直线...记住只需将斜率取倒数即可。 - undefined
当然可以,但是来吧...;-) 帮助提问者找到他的钝角等腰三角形上的第三个点之一。这才是他真正的问题! - undefined
@markE - 这很有帮助,这是我算法的第一步。 - undefined
1
@Hogan 我同意你的观点,一个好的答案需要更多的步骤 :-) 实际上,我的评论是想促使musicfuel更充分地回答问题... - undefined
1
给出一个赞,因为你的回答很好!只是提醒一下,如果你偏离主题太远,你的等腰三角形会变成锐角三角形。 - undefined
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接