forked from i-RIC/iriclib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iricsolverlib_tricell.cpp
64 lines (49 loc) · 1.4 KB
/
iricsolverlib_tricell.cpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "iricsolverlib_tricell.h"
#include "iricsolverlib_point2d.h"
#include "iricsolverlib_rect2d.h"
#include <cmath>
#include <vector>
using namespace iRICSolverLib;
namespace {
const double INSIDE_DELTA = 1.0E-8;
} // namespace
TriCell::TriCell(size_t id1, size_t id2, size_t id3, Grid2D* const grid) :
Cell2D(grid)
{
addNode(id1);
addNode(id2);
addNode(id3);
}
TriCell::~TriCell()
{}
bool TriCell::interpolate(const Point2D& point, double* weight) const
{
if (! boundingRect().contains(point)) {return false;}
double s, t, u;
calcSTU(point, node(1), node(2), node(3), &s, &t, &u);
if (s < - INSIDE_DELTA || t < - INSIDE_DELTA || u < - INSIDE_DELTA) {
return false;
}
*(weight) = s;
*(weight + 1) = t;
*(weight + 2) = u;
return true;
}
double TriCell::area() const
{
return calcArea(node(1), node(2), node(3));
}
void TriCell::calcSTU(const Point2D& point, const Point2D& node0, const Point2D& node1,const Point2D& node2, double* s, double* t, double* u)
{
Point2D p = point - node0;
Point2D p1 = node1 - node0;
Point2D p2 = node2 - node0;
double m = p1.x() * p2.y() - p1.y() * p2.x();
*t = (p.x() * p2.y() - p.y() * p2.x()) / m;
*u = - (p.x() * p1.y() - p.y() * p1.x()) / m;
*s = (1 - *t - *u);
}
double TriCell::calcArea(const Point2D& p1, const Point2D& p2, const Point2D& p3)
{
return 0.5 * std::fabs((p2.x() - p1.x()) * (p3.y() - p1.y()) - (p2.y() - p1.y()) * (p3.x() - p1.x()));
}