如果一个点在每条边的左侧(右侧),则该点位于三角形内部。您可以计算由要测试的点和三角形顶点之一以及位于三角形两侧的 3 个矢量构成的矢量的叉积(实际上只是其中的一个分量)(全部按顺时针方向或全部逆时针方向)。查看所有 3 个的计算分量是否具有相同的符号(所有 3 个负数或所有 3 个正数)。这会告诉你重点。速度快,精度没有问题,至少,如果你使用整数来完成任务。
一旦你看到它在三角形边之一的错误边上,你可以停止对每个点的进一步计算。
C中的示例代码:
#include <stdio.h>
#define SCREEN_HEIGHT 22
#define SCREEN_WIDTH 78
// Simulated frame buffer
char Screen[SCREEN_HEIGHT][SCREEN_WIDTH];
void SetPixel(int x, int y, char color)
{
if ((x < 0) || (x >= SCREEN_WIDTH) ||
(y < 0) || (y >= SCREEN_HEIGHT))
return;
Screen[y][x] = color;
}
void Visualize(void)
{
int x, y;
for (y = 0; y < SCREEN_HEIGHT; y++)
{
for (x = 0; x < SCREEN_WIDTH; x++)
printf("%c", Screen[y][x]);
printf("\n");
}
}
typedef struct
{
int x, y;
} Point2D;
int main(void)
{
// triangle vertices
Point2D vx0 = { SCREEN_WIDTH / 2, SCREEN_HEIGHT / 7 };
Point2D vx1 = { SCREEN_WIDTH * 6 / 7, SCREEN_HEIGHT * 2 / 3 };
Point2D vx2 = { SCREEN_WIDTH / 7, SCREEN_HEIGHT * 6 / 7 };
// vectors lying on triangle sides
Point2D v0, v1, v2;
// current point coordinates
int x, y;
// calculate side vectors
v0.x = vx1.x - vx0.x;
v0.y = vx1.y - vx0.y;
v1.x = vx2.x - vx1.x;
v1.y = vx2.y - vx1.y;
v2.x = vx0.x - vx2.x;
v2.y = vx0.y - vx2.y;
// process all points
for (y = 0; y < SCREEN_HEIGHT; y++)
for (x = 0; x < SCREEN_WIDTH; x++)
{
int z1 = (x - vx0.x) * v0.y - (y - vx0.y) * v0.x;
int z2 = (x - vx1.x) * v1.y - (y - vx1.y) * v1.x;
int z3 = (x - vx2.x) * v2.y - (y - vx2.y) * v2.x;
if ((z1 * z2 > 0) && (z1 * z3 > 0))
SetPixel(x, y, '+'); // point is to the right (left) of all vectors
else
SetPixel(x, y, '-');
}
// draw triangle vertices
SetPixel(vx0.x, vx0.y, '0');
SetPixel(vx1.x, vx1.y, '1');
SetPixel(vx2.x, vx2.y, '2');
// visualize the result
Visualize();
return 0;
}
输出(ideone):
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
---------------------------------------0--------------------------------------
--------------------------------------++++------------------------------------
------------------------------------++++++++----------------------------------
----------------------------------+++++++++++++-------------------------------
--------------------------------+++++++++++++++++-----------------------------
------------------------------++++++++++++++++++++++--------------------------
----------------------------++++++++++++++++++++++++++------------------------
--------------------------+++++++++++++++++++++++++++++++---------------------
-------------------------++++++++++++++++++++++++++++++++++-------------------
-----------------------+++++++++++++++++++++++++++++++++++++++----------------
---------------------+++++++++++++++++++++++++++++++++++++++++++--------------
-------------------+++++++++++++++++++++++++++++++++++++++++++++++1-----------
-----------------++++++++++++++++++++++++++++++++++++-------------------------
---------------++++++++++++++++++++++++---------------------------------------
-------------++++++++++++-----------------------------------------------------
-----------2------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------