Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom EuclideanDistance #1120

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Meshes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ using Random
using Bessels: gamma
using Unitful: AbstractQuantity, numtype
using StatsBase: AbstractWeights, Weights, quantile
using Distances: PreMetric, Euclidean, Mahalanobis
using Distances: PreMetric, MinkowskiMetric, Euclidean, Mahalanobis
using Distances: Haversine, SphericalAngle
using Distances: evaluate, result_type
using Rotations: Rotation, QuatRotation, Angle2d
using Rotations: rotation_between
using CoordRefSystems: Basic, Projected, Geographic
Expand All @@ -37,8 +36,8 @@ import Base: ==, !
import Base: +, -, *
import Base: <, >, ≤, ≥
import StatsBase: sample
import Distances: evaluate
import NearestNeighbors: MinkowskiMetric
import Distances: evaluate, result_type
using NearestNeighbors: eval_pow, eval_diff

# Transforms API
import TransformsBase: Transform, →
Expand Down Expand Up @@ -558,6 +557,7 @@ export
measurematrix,
adjacencymatrix,
atol,
EuclideanDistance,

# visualization
viz,
Expand Down
45 changes: 45 additions & 0 deletions src/distances.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,51 @@
# flip arguments so that points always come first
evaluate(d::PreMetric, g::Geometry, p::Point) = evaluate(d, p, g)

# ----------
# EUCLIDEAN
# ----------

struct EuclideanDistance <: MinkowskiMetric end

# Distances.jl interface
result_type(::EuclideanDistance, ::Type{T₁}, ::Type{T₂}) where {T₁,T₂} = float(promote_type(T₁, T₂))

Check warning on line 15 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L15

Added line #L15 was not covered by tests

@propagate_inbounds function (d::EuclideanDistance)(a, b)
@boundscheck if length(a) ≠ length(b)
throw(

Check warning on line 19 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L17-L19

Added lines #L17 - L19 were not covered by tests
DimensionMismatch(
"first collection has length $(length(a)) which does not match the length of the second, $(length(b))."
)
)
end
norm((bᵢ - aᵢ) for (aᵢ, bᵢ) in zip(a, b))

Check warning on line 25 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L25

Added line #L25 was not covered by tests
end

# implementations for geometries
(d::EuclideanDistance)(p₁::Point, p₂::Point) = norm(p₂ - p₁)

Check warning on line 29 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L29

Added line #L29 was not covered by tests

function (d::EuclideanDistance)(p::Point, l::Line)
a, b = l(0), l(1)
u = p - a
v = b - a
α = (u ⋅ v) / (v ⋅ v)
norm(u - α * v)

Check warning on line 36 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L31-L36

Added lines #L31 - L36 were not covered by tests
end

(d::EuclideanDistance)(l::Line, p::Point) = d(p, l)

Check warning on line 39 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L39

Added line #L39 was not covered by tests

function (d::EuclideanDistance)(l₁::Line, l₂::Line)
λ₁, λ₂, r, rₐ = intersectparameters(l₁(0), l₁(1), l₂(0), l₂(1))

Check warning on line 42 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L41-L42

Added lines #L41 - L42 were not covered by tests

if (r == rₐ == 2) || (r == rₐ == 1) # lines intersect or are colinear
zero(result_type(d, lentype(l₁), lentype(l₂)))
elseif (r == 1) && (rₐ == 2) # lines are parallel
d(l₁(0), l₂)

Check warning on line 47 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L44-L47

Added lines #L44 - L47 were not covered by tests
else # get distance between closest points on each line
d(l₁(λ₁), l₂(λ₂))

Check warning on line 49 in src/distances.jl

View check run for this annotation

Codecov / codecov/patch

src/distances.jl#L49

Added line #L49 was not covered by tests
end
end

"""
evaluate(distance::Euclidean, point, line)

Expand Down
Loading