如何在已知中心点 cx
和 cy
以及重心圆的半径的情况下绘制等边三角形?
另外,如何判断一个点是否在三角形内部?
注:我正在为 android
构建此功能,但该问题与编程语言无关。
如何在已知中心点 cx
和 cy
以及重心圆的半径的情况下绘制等边三角形?
另外,如何判断一个点是否在三角形内部?
注:我正在为 android
构建此功能,但该问题与编程语言无关。
在上图中,点C很简单,它就是 (cx, cy + r)。
我可以想到两种相当容易的方法来得到点a和b:
第一种方法:假设 (cx, cy) 是原点,通过将点C分别旋转60度和120度来得到a和b。这可以使用下面的公式实现:
也可以参考维基百科上的这篇文章。
第二种方法:画一条穿过点 (c.x, c.y) 并且斜率为-30度的直线。该直线与圆相交的点将是点b。圆由以下方程定义:
( x - c.x )^2 + ( y - c.y )^2 = r^2
(请注意,会有两个交点,请选择正确的那个。)public bool isLeft(Point A, Point B, Point C){
return ((B.x - A.x)*(C.y - A.y) - (B.y - A.y)*( C.x - A.x)) > 0;
}
该方法中,A = 线段的点1,b = 线段的点2,c = 待检查的点。
对于像我这样懒惰的人,只想获得单位圆上等边三角形的坐标的人:
A: (-0.866, -0.5)
B: (0.866, -0.5)
C: (0.0, 1.0)
如果需要不同的位置和/或半径,请将所有值乘以r
,然后将x
坐标加上cx
,将 y
坐标加上cy
。
目前,我只能回答你的第二个问题。只需进行点线相交测试,前提是您已经存储了定义三角形的点。在计算机图形书中可以找到许多相关算法。
编辑:我想出了一种解决您基本问题(查找定义具有cx、cy和半径作为给定数据的等边三角形的3个点)的方法。它依赖于任何三角形的3个角度之和为180度的属性。我需要一些时间进行进一步检查以确保它是正确的。然后,我将编辑我的答案发布它。
完整答案编辑:此算法草图的实现取决于您选择的编程语言和图形API:
希望这可以帮助您。我将尝试添加一些图示来澄清这种方法的步骤。此外,我将编写和测试这些步骤,以确保正确解决您的问题。
9r^2 = a^2 + b^2 + c^2
r^2 = 36, 9r^2 = 324, 324/3 = 108, sqrt(432) = 10.39
一旦我们知道了三角形的每条边的长度(s = 10.39),我们可以计算x坐标。将s/2(5.2)加到Bx(14.2)的cx上,从Ax(3.8)的cx中减去s/2。
x现在已经解决,需要y
说到s/2,如果我们沿着垂直线将三角形分成两半(从点C到A和B之间的中点),我们就可以解出y(最终给出Ay和By):
a^2 + b^2 = c^2
a^2 + 27.04 (1/2 s squared) = 107.95 (length s squared)
a^2 = 80.91
sqrt(80.91) = 8.99
Center ( 9.00, 9.00)
C ( 9.00,15.00)
B (14.20, 6.01)
A ( 3.80, 6.01)
结论
已知等边三角形的边长后,可以通过给定中心点、外接圆半径和水平基线来计算点的坐标。
mA = new PointD();
mB = new PointD();
mC = new PointD();
mCos120 = Math.cos(AppHelper.toRadians(120));
mSin120 = Math.sin(AppHelper.toRadians(120));
mCos240 = Math.cos(AppHelper.toRadians(240));
mSin240 = Math.sin(AppHelper.toRadians(240));
double r = 30; // this is distance from the center to one of triangle's point.
mA.set(0 + r, 0);
mB.x = mA.x * mCos120 - mA.y * mSin120;
mB.y = mA.x * mSin120 + mA.y * mCos120;
mC.x = mA.x * mCos240 - mA.y * mSin240;
mC.y = mA.x * mSin240 + mA.y * mCos240;
mA = AppHelper.toScreenCoordinates(mCenterPoint, mA);
mB = AppHelper.toScreenCoordinates(mCenterPoint, mB);
mC = AppHelper.toScreenCoordinates(mCenterPoint, mC);
mPlayPath.reset();
mPlayPath.moveTo(mA.getX(), mA.getY());
mPlayPath.lineTo(mB.getX(), mB.getY());
mPlayPath.lineTo(mC.getX(), mC.getY());
mPlayPath.lineTo(mA.getX(), mA.getY());
mPlayPath.close();
public static PointD toScreenCoordinates(PointD center, PointD point) {
return new PointD(point.x + center.x, center.y - point.y);
}
PointD类似于PointF,但使用的是双精度类型。
这是我的Python实现,希望能帮到你:
def construct_eq_triangle(centroid, radius):
side_length = radius * math.sqrt(3)
# Calculate three vertices of the triangle
a = [centroid[0], centroid[1] + (math.sqrt(3) / 3) * side_length] # Top vertex
b = [centroid[0] - (side_length / 2), centroid[1] - (math.sqrt(3) / 6) * side_length] # Bottom left vertex
c = [centroid[0] + (side_length / 2), centroid[1] - (math.sqrt(3) / 6) * side_length] # Bottom right vertex
return a, b, c
你可以用任意值替换side_length
,也可以将centroid
转换为具有2个元素的tuple
或list
,第一个元素是x
,第二个元素是y
。