**Notice**

**Recent Posts**

**Recent Comments**

**Link**

일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|

1 | 2 | 3 | ||||

4 | 5 | 6 | 7 | 8 | 9 | 10 |

11 | 12 | 13 | 14 | 15 | 16 | 17 |

18 | 19 | 20 | 21 | 22 | 23 | 24 |

25 | 26 | 27 | 28 | 29 | 30 | 31 |

**Tags**

- 스칼라 동시성
- 파이썬 데이터분석
- Actor
- 이더리움
- 스위프트
- play 강좌
- 그라파나
- 블록체인
- 파이썬 동시성
- play2 강좌
- CORDA
- 파이썬 강좌
- hyperledger fabric
- 플레이프레임워크
- 하이브리드앱
- Hyperledger fabric gossip protocol
- Golang
- Play2 로 웹 개발
- Play2
- akka 강좌
- 하이퍼레저 패브릭
- 파이썬
- 안드로이드 웹뷰
- 주키퍼
- Akka
- Adapter 패턴
- 스칼라
- 스칼라 강좌
- 파이썬 머신러닝
- 엔터프라이즈 블록체인

**Archives**

- Today

- Total

**관리 메뉴**

## HAMA 블로그

## 메쉬 제네레이션 - delaunay triangulation 본문

http://www.codeproject.com/Articles/492435/Delaunay-Triangulation-For-Fast-Mesh-Generation (펌)

## Introduction

Ten years ago, computing meshes for surfaces in real time for surfaces wasn't realistic, and having a customizable source code module wasn't available either. There are faster versions, but they are large implementations and they are hard to read and modify. With modern computers and modern languages, not only can simple meshes be generated in real time, the code can be written in ways easy to understand. It is the authors opinion that computational geometry and computer vision are entering a new age where real time processing is realistic for a growing set of problems. The code is designed to be reused such that a vertex can be used to both generate the mesh, but also be apart of other data structures and track other aspects at a given point.

To form a surface that can be shaded by a graphics card, the goal is to create a list of vertexes, and a list of triplet indexes of the vertexes that form counter clockwise triangles. Whether it is to visualize a differential equation solved by finite element modeling (FEM) or to view a shape of an object in 3D, the first step is to form the triangle mesh. Usually selecting a set of points is easy, For simple objects like a cylinder or sphere, the point generation leads directly to triangle generation. Generating a mesh from an arbitrary set of points is where Delaunay's Triangulation proves valuable. The goal of the code wasn't to compute the ideal triangulation, but instead produce a “good enough” solution for most practical 3D or FEM problems and do so quickly. Thus the code recursively improves the triangulation after adding each point to either a recursion count is reached or it is an ideal Delaunay triangulation. This limits how long a mesh can take to compute and avoids infinite recursion should there be a software bug.

## Background

Delaunay's Triangulation is named for Boris Delaunay. The general idea is to form a mesh where each triangle's three points lie on the edge of a circle that doesn't contain any other point. This means given any two adjacent triangle's (quadrilateral) the sum of the angles opposite the dividing line are less than 180 degrees.

Triangle mesh a,b,d and b, c, d don't meet the Delaunay condition. But b,c,a and c,d,a do. This is because angle bcd + dab > 180, but abc+cda < 180. This forces the mesh to have triangles that tend to be as close to evenly spaced as possible.

The Bowyer Watson algorithm iteratively adds a point at a time to a mesh to transform it from one Delaunay mesh to another. The general algorithm works by deleting all triangles whose circumscribed circle contains the new point and reform the mesh. The code provided takes a simpler approach.

From top to bottom, the triangles are flipped to meet the Delaunay condition with 3 points:

This does the same thing but with seven points. Note how at first the triangles are mostly slivers and other triangles are huge.

After one level of flipping per insertion the meshing is more regular (below).

After a second round of flipping, the effects of the first flip are then flipped as needed (below).

## Design

### Mesh Generation

The Bower-Watson algorithm is a bit complex because:

- Adding one point may cause a set of triangles to be deleted, and reformed.
- Reforming the set at once explores forming many possible triangulations.
- One must search for the affected triangle's.
- There isn't a pattern for adjusting the mesh in an ordered fashion.

The “hull” based techniques that are also commonly used spiral out from a point and reform the triangulation from the inside out. This approach is nice because it takes an ordered approach to computing and recomputing the mesh. The disadvantage as the software is recomputing the circle for each triangle and sorting through the triangles in real time.

The code provided takes a hybrid approach that forms a linked list of triangles. Each triangle consists of three vertexes, and each side, there is a pointer to the adjacent triangle (or null). The code has the following advantages:

- Each triangle has a link to its neighbors.
- Recursion explores outward if a triangle is altered, its neighbors may be affected (no circles).
- Triangles aren't not generally deleted, they are added or modified.

- Compute the bounding rectangle:
Find the triangle containing the new point (for example, abc), and replace the old triangle 1 with three new triangles.

Repair the pointers:

Examine each triangle and it's outward adjacent:. For example bec shares a side with bdc.

Examine the angles across from the adjacent sides. If greater than 180 degrees, flip the adjacent line.

If the triangle is not flipped skip to step 10.

Reform the old triangles into the new triangles, fix the triangle edges.

For each triangle and it's adjacent triangle repeat steps 5-8 recursively.

Note that a->b->c is counter clockwise, so if it had a face rendered by say direct3D, it would face out from the page. Triangle c->b->a is clockwise so it's face is toward the page. As long as the direction is maintained, the start point isn't relevant, so bdc is the same as dcb or cbd. This concept in abstract algebra is often called commutation.

In memory at this point:

Triangle 1 = a,b,c, and side b,c = triangle 2.

Triangle 2 = bdc, and c,b = triangle 1.

abe with side be should point to ebc.

Abe with side ea should point to aec.

Etc.

Then repair those old adjacent triangles that used to point to abc: bdc side bc used to point to abc, make it point to ebc.

### Triangle Contains a Point

The key to the algorithm is finding the correct triangle to modify.

Classically, a triangle contains a point if it is on the interior side. If a line passes through two points, the line is often expressed as y = mx + b, where m is the slope, and b is the x=0 intercept. The area above the line can be expressed as y > mx+b. So, I a triangle has edge s, r and the other point is t. Then if test point p, is on the same side of the inequality as the point t, then the test point p is on the same side of the line as the other vertex.

This means to compute if a point p is inside, the code compares to see if it's on the same side as the vertex for an edge. That is a lot of computations. Caching the information speeds up the comparison but not enough. Most triangles don't contain the point, and the point is not anywhere near the triangle. To accelerate the computations, only points that are near the triangle need to be tested using the classical method. The software computes the distance between each vertex and the triangle's center. If the point is not closer than this distance it does not need to be tested.

### Acceleration

The triangle objects cache information calculated on demand to form the mesh. When a triangle is "flipped" with it's neighbor, two of it's side's change but two of the points remain. When a vertex moves, it invalidates the existing information about those edges.

For example, the center of a triangle changes if any vertex changes, setting points A, B, C sets the calculated to false, asking for the center calculates it ans sets the flag.

```
Vertex m_Center;
public Vertex Center
{
get
{
if (m_centerComputed) return m_center;
m_center = new Vertex(
(A.X + B.X + C.X) / 3f,
(A.Y + B.Y + C.Y) / 3f,
(A.Z + B.Z + C.Z) / 3f);
float delta = m_center.DeltaSquared(A);
float tmp = m_center.DeltaSquared(B);
delta = delta > tmp ? delta : tmp;
tmp = m_center.DeltaSquared(C);
delta = delta > tmp ? delta : tmp;
FarthestFromCenter = delta;
m_centerComputed = true;
return m_center;
}
}
```

Once the center is computed the software can reuse this information and it is only then recalculated on demand.

#### '그래픽스' 카테고리의 다른 글

Ease in / out 보간법 (펌) (0) | 2015.07.22 |
---|---|

메쉬 생성 방법 소개 (0) | 2015.07.21 |

**Comments**