On Wed, Sep 8, 2010 at 1:02 AM, Matthew Kenworthy
<[email protected]> wrote:
> Hi Puneet,
>
> Whoops, I forgot the pathological case of a vertical line. Here's some
> corrected code that will select your polygon.


I am going to check this out more tomorrow, but a quick check shows
that it almost works (I could be wrong in my test... I am very, very
sleepy). What is happening is that your program seems to be choosing
points "completely within" but not always... sometimes it is choosing
points that the lines "pass through." But, that said, I could have
likely made a mistake in my spot checks. Will do more detailed testing
tomorrow.

This is pretty slick though.

I have a rather crude point_in_polygon version cobbled together, but
that is so un-PDL-ish that it is embarrassing.


>
> Cheers,
>
> Matt
>
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> use PDL;
> use PDL::NiceSlice;
> use PDL::Graphics::PGPLOT;
>
> my $x = pdl (2, 25,  27, 7, 2); # N points
> my $y = pdl (2, 5,  21, 24, 14); # N points
>
> my $im = grandom (35,35); # test image
>
> # with N points there are N connecting lines assuming a closed curve
> my $dx = $x - $x->rotate(1);
> my $dy = $y - $y->rotate(1);
>
> # avoid pathological case where dx = 0
> $dx->where(abs($dx) < 1e-6) .= 1e-6;
>
> # equation of a line is y = mx + c
> # calculate m
> my $m = $dy / $dx;
>
> # solve for c given m, x and y
> my $c = $y - ($m * $x);
>
> # so we have N line equations and we want to make a stack of masks that
> # are [N, dims($im)] with eacn of the N mask images representing the
> # inequality of the y > mx + c
> my $mask = ( (yvals($im)->dummy(0)) > ($m * (xvals($im)->dummy(0)) + $c) );
>
> # but how do we pick the correct < or > in the inequality above?
>
> # calculate the mean point of x and y and
> # define that point to be inside the polygon
> my $x0 = avg($x);
> my $y0 = avg($y);
>
> # find all the N planes in $mask that have ($x0, $y0) == 1
> my $flip_it = $mask(,$x0,$y0);
> # we define points within the polygon to be 0
> $mask = abs($mask - $flip_it);
>
> # where $mask == 0 is the required mask
>
>
> my $selected_mask = ($mask->sumover < 1);
>
> imag $selected_mask;
>
> On Wed, Sep 8, 2010 at 3:31 AM, P Kishor <[email protected]> wrote:
>>
>> Rectangular selections from 2D piddles are easy and fast with the
>> range operator. However, I would like to grab a non-rectangular
>> selection out of a piddle, setting all out-of-area-of-interest
>> elements to BAD.
>>
>> Background --
>>
>> - The user clicks on a map and creates an irregular polygon
>> - I (somehow **) figure out the piddle elements, aka cells, that lie
>> within the drawn poly
>> - Out of the base piddle, I grab the tightest rect that contains the
>> cells within the drawn poly (the min. bounding box)
>> - Set all the cells outside the drawn poly to BAD so they don't figure
>> in the rest of the calculations
>>
>
> --
> Matthew Kenworthy / Assistant Professor / Leiden Observatory
> Niels Bohrweg 2 (#463) / P.O. Box 9513 / 2300 RA Leiden / NL
>
>



-- 
Puneet Kishor http://www.punkish.org
Carbon Model http://carbonmodel.org
Charter Member, Open Source Geospatial Foundation http://www.osgeo.org
Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor
Nelson Institute, UW-Madison http://www.nelson.wisc.edu
-----------------------------------------------------------------------
Assertions are politics; backing up assertions with evidence is science
=======================================================================

_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to