11

cx给定圆心和cy 圆心圆的半径,如何绘制等边三角形?

我如何找到一个点是否在三角形内?

在此处输入图像描述

PS:我正在为 构建这个android,但这个问题与语言无关。

4

6 回答 6

16

对于你的第一个问题

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

我可以想到两种相当简单的方法来获得点 a 和 b:

第一种方法:假设 (cx,cy) 是原点,将点 C 旋转 60 度和 120 度以获得 a 和 b。这可以通过以下公式来完成:

  • bx = cx * cos( 120 度 ) - ( cy * sin( 120 度 ) )
  • by = cx * sin( 120 度 ) + ( cy * cos( 120 度 ) )
  • ax = cx * cos( 240 度 ) - ( cy * sin( 240 度 ) )
  • ay = cx * sin( 240 度) + ( cy * cos( 240 度))

另请查看wikipedia 上的这篇文章

第二种方法:画一条穿过 (cx, cy) 且斜率为 -30 度的线。该线与圆相交的地方将是点b。圆由以下等式定义:

 ( x - c.x )^2 + ( y - c.y )^2 = r^2 

(注意,会有两个交点,所以选择正确的一个)。

然后对通过 (cx, cy) 的正 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 = line point1、b = line point2 和 c = 要检查的点。

于 2012-07-13T23:38:11.757 回答
11

对于任何只想在单位圆上获得等边三角形坐标的懒惰人(比如我):

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

对于不同的位置和/或半径,将所有值乘以r,然后添加cxx坐标和cys y

于 2017-07-31T08:24:12.080 回答
1

此刻,我只能回答你的第二个问题。只要您存储了定义三角形的点,就可以进行点线相交测试。您可以在计算机图形书籍中找到许多相关的算法。

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

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

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

希望有帮助。我将尝试添加一些图纸以进一步阐明此方法的步骤。此外,我将对这些步骤进行编程和测试,以确保正确解决您的问题。

于 2012-07-12T10:35:26.113 回答
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 坐标。Bx (14.2) 将 s/2 (5.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)

结论

一旦我们知道等边三角形的边长,就可以在给定中心点、外接圆半径和水平底边的情况下计算点坐标。

于 2014-05-17T01:33:50.327 回答
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 类似,但具有 double 类型。

于 2015-11-27T19:50:58.073 回答
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 个元素的 atuple或 a list,第一个是 the x,第二个是y

于 2021-01-02T21:42:44.013 回答