Thank you @baggepinnen, but I must have explained my self poorly. I wanted to remove all the points that were between the edge-points of a collinear collection.
I ended up with the following method:
First a function that detects if 3 points lie on a line, and if so, return the point in the middle:
function find_collinear(xy)
inds = ((1, 2), (1, 3), (2, 3))
Δ = [norm(xy[i1] - xy[i2]) for (i1, i2) in inds]
M, i = findmax(Δ)
j, l = setdiff(1:3, i)
Δ[j] + Δ[l] ≈ M && return only(setdiff(1:3, inds[i]))
nothing
end
Then, if I use your MWE data, I can iterate over all combinations of 3 points, test to see if they are collinear and return the index to middle point (that I want to later remove):
data = [1:10 [zeros(4); 1; zeros(5)]]
xy = SVector{2, Float64}.(eachrow(data))
k = Int[]
for j in combinations(1:length(xy), 3)
if !any(∈(k), j)
i = find_collinear(xy[j])
updatek!(k, j, i)
end
end
where updatek!
is just a helper function to push!
the culprit into k
:
updatek!(k, j, ::Nothing) = nothing
updatek!(k, j, i) = push!(k, j[i])
and a final plot:
scatter(xy)
scatter!(xy[k], color = :red)
As you can see, all the points in red lie on a line between two edge points, I wanna keep those edge points as well as all the non-collinear points in the collection:
julia> deleteat!(xy, k)
3-element Array{SArray{Tuple{2},Float64,1,2},1}:
[1.0, 0.0]
[5.0, 1.0]
[10.0, 0.0]