三角形有时是等边的,有时不是?

时间:2016-04-01 20:04:55

标签: c++ list math vertex

我试图在控制台屏幕上生成随机等边三角形。

我正在使用的方法是创建三角形的中心点(随机定位),将中心点移动到原点(0,0),然后从中心创建3个点(添加半径(随机数))每个点的Y轴三角形)。然后我旋转2个点,一个在120度,另一个在240,形成一个等边三角形,然后在点之间画线。然后将点返回到与质心相关的原始图。

这在过去最常见的时候起作用,我得到一个等边三角形,但有时候我不会得到一个等边三角形而且我完全不知道为什么。

我正在使用Brensenham的线算法绘制点之间的界线。

工作三角形的图像:http://imgur.com/GpF406O

破碎三角形的图像:http://imgur.com/Oa2BYun

以下是绘制三角形坐标的代码:

void Triangle::createVertex(Vertex cent)
{
// angle of 120 in radians
double s120 = sin(2.0943951024);
double c120 = cos(2.0943951024);
// angle of 240 in radians
double s240 = sin(4.1887902048);
double c240 = cos(4.1887902048);

// bringing centroid to the origin and saving old pos to move later on
int x = cent.getX();
int y = cent.getY();
cent.setX(0);
cent.setY(0);

// creating the points all equal distance from the centroid
Vertex v1(cent.getX(), cent.getY() + radius);
Vertex v2(cent.getX(), cent.getY() + radius);
Vertex v3(cent.getX(), cent.getY() + radius);

// rotate points
double newx = v1.getX() * c120 - v1.getY() * s120;
double newy = v1.getY() * c120 + v1.getX() * s120;

double xnew = v2.getX() * c240 - v2.getY() * s240;
double ynew = v2.getY() * c240 + v2.getX() * s240;

// giving the points the actual location in relation the the old pos of the centroid
v1.setX(newx + x);
v1.setY(newy + y);

v2.setX(xnew + x);
v2.setY(ynew + y);

v3.setX(x);
v3.setY(y + radius);

// adding the to a list (list is used in a function to draw the lines)
vertices.push_back(v1);
vertices.push_back(v2);
vertices.push_back(v3);
}

1 个答案:

答案 0 :(得分:1)

查看两个三角形的图像(并查看线条绘制算法),您将线条绘制为一系列离散像素。这意味着顶点必须落在像素中(它不能在边界上),就像在image中一样。

那么如果您的顶点落在像素之间的边界上会发生什么?您的线条绘制算法必须决定放置顶点的​​像素。

查看wikipedia上的算法描述和页面上的c ++实现www.cs.helsinki.fi 我看到两个列表实现都使用整数运算**,在这种情况下,如果你有一些谨慎的像素行,这种情况并不合理。这意味着如果您的浮点计算在完成楼层(从float到int的转换)时将一个顶点放在下一行像素的整数标签的阈值之上,但另一个顶点低于该阈值,那么这两个顶点将放在不同的行上。

认为v1.y = 5.00000000000000000001v2.y = 4.99999999999999999999导致v1被放置在第5行,而v2被放置在第4行。

这解释了为什么你只看到偶尔出现的问题,你偶尔会让你的顶点落在这样的边界上。

为了解决一些事情,我想到了:

在为顶点指定值时修复它,y值无论如何都是相同的。

下式给出:

v1.getX() = v2.getX() = 0 (defined by your code)
v1.getY() = v2.getY() = radius (defined by your code)
cos(120 degrees) = cos(240 degrees) ('tis true)

这会将您的两个y值减少到

double newy = v1.getY() * c120
double ynew = v1.getY() * c120

麦角:

v1.setY(newy + y);
v2.setY(newy + y);

如果您编写了自己的Brensenham算法实现,您可以在该代码中添加一个检查以确保您的顶点处于相同的高度,但这似乎是一个非常糟糕的地方进行这种检查,因为端点的高度特定于您的问题,而不是一般的绘制线。

<小时/> *或者不完全打开,但是在考虑到浮点错误之后你不能说出差异

**算法并不局限于整数运算,但我怀疑你的问题不规则以及算法的呈现方式,以及你在图像中使用谨慎字符的事实整数算术就是问题。