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
