Skip to content

Commit

Permalink
Merge pull request #125 from knuesel/fix-area
Browse files Browse the repository at this point in the history
area and MetaFree fixes
  • Loading branch information
SimonDanisch authored Jan 25, 2021
2 parents b769ca5 + 302fdb0 commit d7fc448
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 23 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.3'
- '1'
- 'nightly'
os:
Expand Down
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ Tables = "0.2, 1"
julia = "1.3"

[extras]
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Random"]
test = ["Test", "Random", "OffsetArrays"]
2 changes: 1 addition & 1 deletion src/metadata.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ macro meta_type(name, mainfield, supertype, params...)
return $MetaName{$(params_sym...),ST,Names,Types}
end

GeometryBasics.MetaFree(::Type{<:$MetaName{Typ}}) where {Typ} = Typ
GeometryBasics.MetaFree(::Type{<:$MetaName{$(params_sym...),Typ}}) where {$(params_sym...), Typ<:$supertype{$(params_sym...)} } = Typ
GeometryBasics.MetaFree(::Type{<:$MetaName}) = $name
GeometryBasics.metafree(x::$MetaName) = getfield(x, :main)
GeometryBasics.metafree(x::AbstractVector{<:$MetaName}) = getproperty(x, $field)
Expand Down
24 changes: 14 additions & 10 deletions src/triangulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,28 @@ function area(vertices::AbstractVector{<:AbstractPoint{3,VT}},
return sum(x -> area(vertices, x), faces)
end

function area(contour::AbstractVector{<:AbstractPoint{N,T}}) where {N,T}
n = length(contour)
n < 3 && return zero(T)
"""
area(contour::AbstractVector{AbstractPoint}})
Calculate the area of a polygon.
For 2D points, the oriented area is returned (negative when the points are
oriented clockwise).
"""
function area(contour::AbstractVector{<:AbstractPoint{2,T}}) where {T}
length(contour) < 3 && return zero(T)
A = zero(T)
p = lastindex(contour)
q = firstindex(contour)
while q <= n
for q in eachindex(contour)
A += cross(contour[p], contour[q])
p = q
q += 1
end
return A * T(0.5)
end

function area(contour::AbstractVector{Point{3,T}}) where {T}
function area(contour::AbstractVector{<:AbstractPoint{3,T}}) where {T}
A = zero(eltype(contour))
o = contour[1]
o = first(contour)
for i in (firstindex(contour) + 1):(lastindex(contour) - 1)
A += cross(contour[i] - o, contour[i + 1] - o)
end
Expand All @@ -59,8 +64,7 @@ end
"""
in(point, triangle)
InsideTriangle decides if a point P is Inside of the triangle
defined by A, B, C.
Determine if a point is inside of a triangle.
"""
function Base.in(P::T, triangle::Triangle) where {T<:AbstractPoint}
A, B, C = coordinates(triangle)
Expand Down
9 changes: 0 additions & 9 deletions test/geometrytypes.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
using Test, GeometryBasics

@testset "algorithms.jl" begin
cube = Rect(Vec3f0(-0.5), Vec3f0(1))
cube_faces = decompose(TriangleFace{Int}, faces(cube))
cube_vertices = decompose(Point{3,Float32}, cube)
@test area(cube_vertices, cube_faces) == 6
mesh = Mesh(cube_vertices, cube_faces)
@test GeometryBasics.volume(mesh) 1
end

@testset "Cylinder" begin
@testset "constructors" begin
o, extr, r = Point2f0(1, 2), Point2f0(3, 4), 5.0f0
Expand Down
30 changes: 28 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
using Test, Random, StructArrays, Tables, StaticArrays
using Test, Random, StructArrays, Tables, StaticArrays, OffsetArrays
using GeometryBasics
using LinearAlgebra
using GeometryBasics: attributes

@testset "GeometryBasics" begin

@testset "algorithms" begin
cube = Rect(Vec3f0(-0.5), Vec3f0(1))
cube_faces = decompose(TriangleFace{Int}, faces(cube))
cube_vertices = decompose(Point{3,Float32}, cube)
@test area(cube_vertices, cube_faces) == 6
mesh = Mesh(cube_vertices, cube_faces)
@test GeometryBasics.volume(mesh) 1

points_cwise = Point2f0[(0,0), (0,1), (1,1)]
points_ccwise = Point2f0[(0,0), (1,0), (1,1)]
@test area(points_cwise) -0.5
@test area(points_ccwise) 0.5
@test area(OffsetArray(points_cwise, -2)) -0.5

points3d = Point3f0[(0,0,0), (0,0,1), (0,1,1)]
@test area(OffsetArray(points3d, -2)) 0.5

pm2d = [PointMeta(0.0, 0.0, a=:d), PointMeta(0.0, 1.0, a=:e), PointMeta(1.0, 0.0, a=:f)]
@test area(pm2d) -0.5

pm3d = [PointMeta(0.0, 0.0, 0.0, a=:d), PointMeta(0.0, 1.0, 0.0, a=:e), PointMeta(1.0, 0.0, 0.0, a=:f)]
@test_broken area(pm3d) 0.5 # Currently broken as zero(PointMeta(0.0, 0.0, 0.0, a=:d)) fails
end

@testset "embedding metadata" begin
@testset "Meshes" begin

Expand Down Expand Up @@ -84,13 +108,15 @@ using GeometryBasics: attributes
@testset "point with metadata" begin
p = Point(1.1, 2.2)
@test p isa AbstractVector{Float64}
pm = GeometryBasics.PointMeta(1.1, 2.2; a=1, b=2)
pm = PointMeta(1.1, 2.2; a=1, b=2)
p1 = Point(2.2, 3.6)
p2 = [p, p1]
@test coordinates(p2) == p2
@test meta(pm) === (a=1, b=2)
@test metafree(pm) === p
@test propertynames(pm) == (:position, :a, :b)
@test GeometryBasics.MetaFree(typeof(pm)) == Point{2,Float64}
@test_broken zero(pm) == [0, 0]
end

@testset "MultiPoint with metadata" begin
Expand Down

0 comments on commit d7fc448

Please sign in to comment.