给出中心绘制等边三角形

时间:2012-07-12 10:25:01

标签: language-agnostic drawing shape

如果中心为cxcy,如何绘制等边三角形? 和质心圆的半径?

如何判断一个点是否在三角形内?

enter image description here

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

6 个答案:

答案 0 :(得分:12)

第一个问题

上图中的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度))

另请查看this article on wikipedia

第二种方法:绘制一条穿过(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的左边。

here引用的以下方法可让您检查某个点是否位于向量的左侧。

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 =指向要检查的位置。

答案 1 :(得分:1)

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

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

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

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

希望有所帮助。我将尝试添加一些图纸,以澄清这种方法的更多步骤。此外,我将编程并测试这些步骤,以确保正确解决您的问题。

答案 2 :(得分:1)

我需要使用SVG和Javascript绘制等边三角形......

我尝试了Xantix对第一个问题的回答,以便在给定中心点(cx,cy)和外接圆半径(r)的情况下绘制等边三角形,正如所指出的那样,它可以很容易地求解坐标。 C点(cx,cy + r)。

然而,我无法弄清楚如何获得旋转方程来解决A点和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)添加到cx用于Bx(14.2),并从cx中减去s / 2用于Ax(3.8)。

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中减去这个y值(15 - 8.99 = 6.01)给出了我们对A点和B点的新y图。

Center ( 9.00, 9.00)
C      ( 9.00,15.00)
B      (14.20, 6.01)
A      ( 3.80, 6.01)

<强>结论

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

答案 3 :(得分:1)

对于懒惰(像我一样)只想要单位圆上等边三角形坐标的人:

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

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

答案 4 :(得分: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,但是具有双重类型。

答案 5 :(得分: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 替换为 tuple 或具有 2 个元素的 list,第一个是 {{1 }} 第二个是 x