Thanks, René, seems like it's the most simple and intuitive approach. In
fact, it looks very similar to what I've got after porting SciKit Image
version. Here's my code:
function inpolygon{T<:Number}(x:: T, y:: T, vx:: Vector{T}, vy:: Vector{T})
@assert length(vx) == length(vy)
c = false
j = length(vx)
@inbounds for i=1:length(vx)
if (((vy[i] <= y && y < vy[j]) ||
(vy[j] <= y && y < vy[i])) &&
(x < (vx[j] - vx[i]) * (y - vy[i]) / (vy[j] - vy[i]) + vx[i]))
c = !c
end
j = i
end
return c
end
function poly2mask{T<:Number}(vx::Vector{T}, vy::Vector{T}, m::Int, n::Int)
mask = zeros(Int, m, n)
@inbounds for j=1:m, i=1:n
mask[i, j] = int(inpolygon(j, i, vx, vy))
end
return mask
end
And it works pretty fast - for 10x10 matrix it takes only 2.5 microseconds
on my machine.
On Wednesday, January 28, 2015 at 11:42:29 AM UTC+3, René Donner wrote:
>
> Perhaps the following is what you need. P should be 2 x nPoints. try e.g.
> inpolygon([10 20 20 10; 10 10 20 20],1:50,1:40)
>
>
> function inpolygon(P,m::Int,n::Int)
> j = size(P,2)
> oddnodes = false
> M = P[1,:]
> N = P[2,:]
>
> for i in 1:size(P,2)
> if M[i] < m && M[j] >= m || M[j] < m && M[i] >= m
> if N[i] + (m-M[i]) / (M[j]-M[i]) * (N[j]-N[i]) < n
> oddnodes = !oddnodes
> end
> end
> j = i
> end
>
> oddnodes
> end
> inpolygon{T}(P,img::Array{T,2}) = inpolygon(P, 1:size(img,1),
> 1:size(img,2))
> inpolygon(P,M::AbstractArray,N::AbstractArray) = Float32[inpolygon(P, m,n)
> for m in M, n in N]
>
>
>
> Am 28.01.2015 um 03:50 schrieb Steven G. Johnson <[email protected]
> <javascript:>>:
>
> >
> >
> > On Sunday, January 25, 2015 at 11:03:30 AM UTC-5, Andrei Zh wrote:
> > In Matlab, `poly2mask` transforms polygon (given by arrays of `x` and
> `y` coordinates) into a binary mask, where all values inside polygon get
> value 1 and all others get value 0. I found Octave implementation [1] that
> I can translate into Julia, but it's GPL-licensed, and I'd like to avoid
> copyleft to make my library more flexible for users. Are there any better
> options or components in Julia that I can reuse for this task?
> >
> > You wouldn't want to base a Julia version on an Octave or Matlab version
> anyway. Those languages force you to jump through lots of hoop in order to
> vectorize your code, resulting in rather convoluted implementations of
> simple algorithms.
> >
> > In Julia for this problem, I would just write a nested loop: loop over
> points in the mask, and for each point loop over the (ordered) polygon
> edges to check whether the point is in the polygon via the usual algorithm
> (for an edge v1->v2 and a point p, check whether the cross product
> (p-v1)x(v2-v1) has a consistent sign for all the edges). Probably you
> should also start by computing the bounding box of the polygon and restrict
> yourself to looking at mask points inside this bounding box. Should take
> about 30 lines of code, tops.
>
>