给定中心点,如何画一个等边三角形?

11

如何在已知中心点 cxcy 以及重心圆的半径的情况下绘制等边三角形?

另外,如何判断一个点是否在三角形内部?

图片描述

注:我正在为 android 构建此功能,但该问题与编程语言无关。

6个回答

17

关于您的第一个问题

在上图中,点C很简单,它就是 (cx, cy + r)。

我可以想到两种相当容易的方法来得到点a和b:

第一种方法:假设 (cx, cy) 是原点,通过将点C分别旋转60度和120度来得到a和b。这可以使用下面的公式实现:

  • b.x = c.x * cos( 120度 ) - ( c.y * sin( 120度 ) )
  • b.y = c.x * sin( 120度 ) + ( c.y * cos( 120度 ) )
  • a.x = c.x * cos( 240度 ) - ( c.y * sin( 240度 ) )
  • a.y = c.x * sin( 240度 ) + ( c.y * cos( 240度 ) )

也可以参考维基百科上的这篇文章

第二种方法:画一条穿过点 (c.x, c.y) 并且斜率为-30度的直线。该直线与圆相交的点将是点b。圆由以下方程定义:

 ( x - c.x )^2 + ( y - c.y )^2 = r^2 
(请注意,会有两个交点,请选择正确的那个。)
然后,通过从(c.x,c.y)开始的正30度角线重复相同的步骤以获得点a。
你的直线斜率将为:1 / sqrt(3)和-1 / sqrt(3)
对于第二个问题
一旦您获得了形成等边三角形的点A、B和C,最快最简单的检测点(x,y)是否在三角形中的方法之一是基于叉积和向量。
基本上,看看(x,y)是否在“向量”A->B的左侧。然后看看它是否在B->C的左侧。然后检查它是否在C->A的左侧。
以下方法摘自这里,可以让你检查一个点是否在一个向量的左侧。
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 = 待检查的点。


14

对于像我这样懒惰的人,只想获得单位圆上等边三角形的坐标的人:

A: (-0.866, -0.5)
B: (0.866, -0.5)
C: (0.0, 1.0)

如果需要不同的位置和/或半径,请将所有值乘以r,然后将x坐标加上cx,将 y坐标加上cy


2
最简单的解决方案。 :) - Tiberiu Mihai

1

目前,我只能回答你的第二个问题。只需进行点线相交测试,前提是您已经存储了定义三角形的点。在计算机图形书中可以找到许多相关算法。

编辑:我想出了一种解决您基本问题(查找定义具有cx、cy和半径作为给定数据的等边三角形的3个点)的方法。它依赖于任何三角形的3个角度之和为180度的属性。我需要一些时间进行进一步检查以确保它是正确的。然后,我将编辑我的答案发布它。

完整答案编辑:此算法草图的实现取决于您选择的编程语言和图形API:

  • 将2D坐标系的中心(顺时针方向)转移到质心圆的中心。
  • 存储定义两条直线段的2个点以及圆的中心。这些线段的并集可能给出圆的直径。两条线段都有圆的中心作为它们的1个定义点。另外2个定义点(需要存储)在圆的周长上(使用圆的半径长度找到它们)。
  • 将2个点顺时针和逆时针旋转60度,使它们落在圆周上。存储它们的新坐标。画出连接它们的线段。你已经得到了三角形的2个顶点之一。
  • 对坐标系中心进行反向平移。
  • 三角形的剩余顶点是一个圆半径和两条线段的交点,每条线段从其各自已知的三角形顶点开始。
  • 最后,存储顶点并绘制三角形。

希望这可以帮助您。我将尝试添加一些图示来澄清这种方法的步骤。此外,我将编写和测试这些步骤,以确保正确解决您的问题。


感谢,让我试试这个。它看起来相当复杂。 - Gautam

1
我需要使用SVG和Javascript绘制等边三角形......我尝试了Xantix在第一个问题中的答案,以便给定一个中心点(cx,cy)和外接圆半径(r)绘制等边三角形,正如指出的那样,容易解决点C(cx,cy + r)的坐标。然而,我无法弄清楚如何获得旋转方程式来解决点A和B的坐标,因此我的解决方案如下。数学时间-解x的值。假设cx = 9,cy = 9,r = 6,并且有水平基准线。首先,找到三角形的边长(a,b,c):
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

从cy + r (15 - 8.99 = 6.01)减去这个y值,就得到了点A和B的新的y坐标。
Center ( 9.00, 9.00)
C      ( 9.00,15.00)
B      (14.20, 6.01)
A      ( 3.80, 6.01)

结论

已知等边三角形的边长后,可以通过给定中心点、外接圆半径和水平基线来计算点的坐标。


0
这是我用Java(Android)绘制三角形的方法:
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,但使用的是双精度类型。


0

这是我的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个元素的tuplelist,第一个元素是x,第二个元素是y


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