This commit is contained in:
Miloslav Ciz 2022-11-01 21:41:16 +01:00
parent 1ff2170a74
commit 1f9cd12678
10 changed files with 55 additions and 15 deletions

View file

@ -52,3 +52,29 @@ Triangles also play a big role e.g. in [realtime](realtime.md) [3D rendering](3d
**Winding** of the triangle says whether the ordered vertices of the triangle go clockwise or counterclockwise. I.e. winding says whether if we were to go in the direction *A -> B -> C* we'd be going clockwise or counterclockwise around the triangle center. This is important e.g. for [backface culling](backface_culling.md) in computer graphics (determining which side of a triangle in 3D we are looking at). Determining of the winding of triangle can be derived from the sign of the z-component of the [cross product](cross_product.md) of the triangle's sides. For the lazy: compute *w = (y1 - y0) * (x2 - x1) - (x1 - x0) * (y2 - y1)*, if *w > 0* the points go clockwise, if *w < 0* the points go counterclockwise, otherwise (*w = 0*) the points lie on a line.
[Sierpinski triangle](sierpinski_triangle.md) is a [fractal](fractal.md) related to triangles.
**Testing if point lies inside 2D triangle**: one way to do this is following. For each triangle side test whether the winding of the tested point and the side is the same as the winding of whole triangle -- if this doesn't hold for any side, the point is outside the triangle, otherwise it is inside. In order words for each side we are testing whether the tested point and the remaining triangle point are on the same side (int the same half plane). Here is a [C](c.md) code:
```
int pointIsInTriangle(int px, int py, int tp[6])
{
// winding of the whole triangle:
int w = (tp[3] - tp[1]) * (tp[4] - tp[2]) - (tp[2] - tp[0]) * (tp[5] - tp[3]);
int sign = w > 0 ? 1 : (w < 0 ? -1 : 0);
for (int i = 0; i < 3; ++i) // test winding of point with each side
{
int i1 = 2 * i;
int i2 = i1 != 4 ? i1 + 2 : 0;
int w2 = (tp[i1 + 1] - py) * (tp[i2] - tp[i1]) - (tp[i1] - px) * (tp[i2 + 1] - tp[i1 + 1]);
int sign2 = w2 > 0 ? 1 : (w2 < 0 ? -1 : 0);
if (sign * sign2 == -1) // includes edges
//if (sign != sign2) // excludes edges
return 0;
}
return 1;
}
```