Subject: Re: [xsl] XSLT code that implements the Point-in-a-Polygon problem From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 11 Dec 2020 19:33:38 -0000 |
Just looking at the code, wondering why it's using xsl:choose: could you not do all of it in a single XPath expression, even in XSLT 2? Cheers, E. -- Eliot Kimber http://contrext.com o;?On 12/10/20, 1:22 PM, "Roger L Costello costello@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: Hi Folks, I implemented XSLT code to determine if a point p is inside or outside a polygon. See below. Admittedly, the tests that I've done thus far are really simple. See the template rule. I would appreciate it if you see a bug in the code or see where the code can be improved, you would let me know please. /Roger <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="function" exclude-result-prefixes="#all" version="2.0"> <xsl:output method="text" /> <!-- Given a point p, does p reside in the polygon with N edges? This program solves the Point-in-a-Polygon problem. --> <!-- The following code implements in XSLT the C code shown in Solution 1 at this URL: http://www.eecs.umich.edu/courses/eecs380/HANDOUTS/PROJ2/InsidePo ly.html --> <xsl:function name="f:iterate-Over-All-Polygons" as="xs:string"> <xsl:param name="polygon" as="xs:string+" /> <xsl:param name="N" as="xs:integer" /> <xsl:param name="p" as="xs:string" /> <xsl:param name="counter" as="xs:integer" /> <xsl:param name="p1" as="xs:string" /> <xsl:param name="i" as="xs:integer" /> <xsl:variable name="p_x" select="xs:double(tokenize($p, ' ')[1])" as="xs:double" /> <xsl:variable name="p_y" select="xs:double(tokenize($p, ' ')[2])" as="xs:double" /> <xsl:variable name="p1_x" select="xs:double(tokenize($p1, ' ')[1])" as="xs:double" /> <xsl:variable name="p1_y" select="xs:double(tokenize($p1, ' ')[2])" as="xs:double" /> <xsl:choose> <xsl:when test="$i le $N"> <!-- p2 = polygon[i % N] --> <xsl:variable name="p2" select="$polygon[($i mod $N) + 1]" as="xs:string"/> <xsl:variable name="p2_x" select="xs:double(tokenize($p2, ' ')[1])" as="xs:double" /> <xsl:variable name="p2_y" select="xs:double(tokenize($p2, ' ')[2])" as="xs:double" /> <!-- if (p.y > MIN(p1.y,p2.y)) --> <xsl:choose> <xsl:when test="$p_y gt min(($p1_y, $p2_y))"> <!-- if (p.y <= MAX(p1.y,p2.y)) --> <xsl:choose> <xsl:when test="$p_y le max(($p1_y, $p2_y))"> <!-- if (p.x <= MAX(p1.x,p2.x)) --> <xsl:choose> <xsl:when test="$p_x le max(($p1_x, $p2_x))"> <!-- if (p1.y != p2.y) --> <xsl:choose> <xsl:when test="$p1_y ne $p2_y"> <!-- xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x --> <xsl:variable name="xinters" select="($p_y - $p1_y)*($p2_x - $p1_x) div ($p2_y - $p1_y) + $p1_x" as="xs:double" /> <!-- if (p1.x == p2.x || p.x <= xinters) --> <xsl:choose> <xsl:when test="$p1_x eq $p2_x or $p_x le $xinters"> <!-- counter++ --> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter + 1, $p2, $i + 1)" /> </xsl:when> <xsl:otherwise> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p2, $i + 1)" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p2, $i + 1)" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p2, $i + 1)" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p2, $i + 1)" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- p1 = p2 --> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p2, $i + 1)" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:message>Number of times a horizontal ray eminating from p to the right intersects the line segments making up the polygon = <xsl:value-of select="$counter" /></xsl:message> <!-- if (counter % 2 == 0) return(OUTSIDE); else return(INSIDE) --> <xsl:choose> <xsl:when test="($counter mod 2) eq 0"><xsl:text>OUTSIDE</xsl:text></xsl:when> <xsl:otherwise><xsl:text>INSIDE</xsl:text></xsl:other wise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:function> <xsl:function name="f:InsidePolygon" as="xs:string"> <xsl:param name="polygon" as="xs:string+" /> <xsl:param name="N" as="xs:integer" /> <xsl:param name="p" as="xs:string" /> <!-- p1 = polygon[1] --> <xsl:variable name="counter" select="0" as="xs:integer" /> <xsl:variable name="p1" select="$polygon[1]" as="xs:string" /> <xsl:variable name="i" select="1" as="xs:integer" /> <xsl:sequence select="f:iterate-Over-All-Polygons($polygon, $N, $p, $counter, $p1, $i)" /> </xsl:function> <xsl:template match="/"> <xsl:variable name="polygon" as="xs:string+"> <xsl:sequence select="'0 0'" /> <xsl:sequence select="'4 0'" /> <xsl:sequence select="'4 4'" /> <xsl:sequence select="'0 4'" /> <xsl:sequence select="'0 0'" /> </xsl:variable> <xsl:variable name="N" select="5" as="xs:integer" /> <xsl:variable name="p" select="'1 1'" as="xs:string" /> <xsl:sequence select="f:InsidePolygon($polygon,$N, $p)" /> <xsl:variable name="p" select="'-1 1'" as="xs:string" /> <xsl:sequence select="f:InsidePolygon($polygon,$N, $p)" /> <xsl:variable name="p" select="'0 0'" as="xs:string" /> <xsl:sequence select="f:InsidePolygon($polygon,$N, $p)" /> <xsl:variable name="p" select="'0.2 0.5'" as="xs:string" /> <xsl:sequence select="f:InsidePolygon($polygon,$N, $p)" /> </xsl:template> </xsl:stylesheet>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XSLT code that implements, director@xxxxxxxxxxx | Thread | [xsl] [ANN] upcoming courses on XSL, Liam R. E. Quin liam |
Re: [xsl] XSLT code that implements, director@xxxxxxxxxxx | Date | [xsl] [ANN] upcoming courses on XSL, Liam R. E. Quin liam |
Month |