Skip to content

Commit 8de05a1

Browse files
Use more efficient parametric transformation for Tetrahedron (#159)
* Try new transform for tetrahedron * Document algorithm for clarity * Update style for similar Triangle function * Remove obsolete comment * Update comment style * Apply suggestions from code review Co-authored-by: Joshua Lampert <[email protected]> --------- Co-authored-by: Joshua Lampert <[email protected]>
1 parent 16835af commit 8de05a1

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

src/specializations/Tetrahedron.jl

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,28 @@ end
2626
# Parametric
2727
################################################################################
2828

29-
# Map argument domain from [0, 1]³ to Barycentric domain for (::Tetrahedron)(t1, t2, t3)
29+
# Map argument domain from [0, 1]³ to Barycentric domain for (::Tetrahedron)(t₁, t₂, t₃)
3030
function _parametric(tetrahedron::Meshes.Tetrahedron)
31-
function f(t1, t2, t3)
32-
if any(Iterators.map(n -> (n < 0) || (n > 1), (t1, t2, t3)))
33-
msg = "tetrahedron(t1, t2, t3) is not defined for (t1, t2, t3) outside [0, 1]³."
34-
throw(DomainError((t1, t2, t3), msg))
31+
function f(t₁, t₂, t₃)
32+
if any(Iterators.map(n -> (n < 0) || (n > 1), (t₁, t₂, t₃)))
33+
msg = "tetrahedron(t₁, t₂, t₃) is not defined for (t₁, t₂, t₃) outside [0, 1]³."
34+
throw(DomainError((t₁, t₂, t₃), msg))
3535
end
3636

37-
# Take a triangular cross-section at t3
38-
a = tetrahedron(t3, 0, 0)
39-
b = tetrahedron(0, t3, 0)
40-
c = tetrahedron(0, 0, t3)
41-
cross_section = _parametric(Meshes.Triangle(a, b, c))
42-
43-
return cross_section(t1, t2)
37+
#=
38+
Algorithm:
39+
- Form a barycentric tetrahedron bounded by the points [0, 0, 0], [1, 0, 0],
40+
[0, 1, 0], and [0, 0, 1].
41+
- Use t₃ to take a triangular cross-section of the tetrahedron at points
42+
[t₃, 0, 0], [0, t₃, 0], and [0, 0, t₃].
43+
- Use t₂ to take a line segment cross-section of the triangle between
44+
points [t₂t₃, 0, t₃ - t₂t₃] and [0, t₂t₃, t₃ - t₂t₃].
45+
- Use t₁ to select a point along this line segment, i.e. ā + t₁(b̄ - ā).
46+
=#
47+
u₁ = (t₂ * t₃) - (t₁ * t₂ * t₃)
48+
u₂ = t₁ * t₂ * t₃
49+
u₃ = t₃ - (t₂ * t₃)
50+
return tetrahedron(u₁, u₂, u₃)
4451
end
4552
return f
4653
end

src/specializations/Triangle.jl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,24 @@ end
2626
# Parametric
2727
################################################################################
2828

29-
# Map argument domain from [0, 1]² to Barycentric domain for (::Triangle)(t1, t2)
29+
# Map argument domain from [0, 1]² to Barycentric domain for (::Triangle)(t₁, t₂)
3030
function _parametric(triangle::Meshes.Triangle)
31-
function f(t1, t2)
32-
if any(Iterators.map(n -> (n < 0) || (n > 1), (t1, t2)))
33-
msg = "triangle(t1, t2) is not defined for (t1, t2) outside [0, 1]²."
34-
throw(DomainError((t1, t2), msg))
31+
function f(t₁, t₂)
32+
if any(Iterators.map(n -> (n < 0) || (n > 1), (t₁, t₂)))
33+
msg = "triangle(t₁, t₂) is not defined for (t₁, t₂) outside [0, 1]²."
34+
throw(DomainError((t₁, t₂), msg))
3535
end
3636

37-
t1t2 = t1 * t2
38-
return triangle(t1t2, t2 - t1t2)
37+
#=
38+
Algorithm:
39+
- Form a barycentric triangle bounded by the points [0, 0], [1, 0], and [0, 1].
40+
- Use t₂ to take a line segment cross-section of the triangle between points
41+
[0, t₂] and [t₂, 0].
42+
- Use t₁ to select a point along this line segment, i.e. ā + t₁(b̄ - ā).
43+
=#
44+
u₁ = t₁ * t₂
45+
u₂ = t₂ - (t₁ * t₂)
46+
return triangle(u₁, u₂)
3947
end
4048
return f
4149
end

0 commit comments

Comments
 (0)