2024-05-06 19:06:35 +02:00
<?xml version="1.0" encoding="UTF-8"?>
2024-05-06 14:27:40 +02:00
<xsl:transform version= "2.0"
2024-05-03 01:59:58 +02:00
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
2024-05-06 19:06:35 +02:00
xmlns:xs="http://www.w3.org/2001/XMLSchema">
2024-05-03 01:59:58 +02:00
<xsl:output method= "xml" indent= "yes" />
2024-05-03 01:50:50 +02:00
2024-05-03 01:59:58 +02:00
<!-- Déclaration des variables initiales -->
2024-05-06 14:35:12 +02:00
<xsl:variable name= "initial-x" select= "0"
as="xs:double" />
<xsl:variable name= "initial-y" select= "0"
as="xs:double" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "initial-angle" select= "0"
2024-05-03 01:59:58 +02:00
as="xs:double" />
2024-05-03 01:50:50 +02:00
2024-05-06 18:26:50 +02:00
<!-- Séquences pour stocker les états -->
<xsl:variable name= "x-values" select= "()"
as="xs:double*" />
<xsl:variable name= "y-values" select= "()"
as="xs:double*" />
<xsl:variable name= "angle-values"
as="xs:double*" select="()" />
2024-05-06 14:24:53 +02:00
<xsl:template match= "/tortue" >
2024-05-03 01:59:58 +02:00
<xsl:processing-instruction name= "xml-model" > href="traceur.xsd"</xsl:processing-instruction>
2024-05-06 14:35:12 +02:00
2024-05-06 14:24:53 +02:00
<traceur >
<!-- Appel du template pour traiter les commandes
2024-05-06 18:24:07 +02:00
avec les valeurs initiales des paramètres -->
2024-05-03 01:59:58 +02:00
<xsl:call-template name= "process-commands" >
2024-05-06 14:24:53 +02:00
<xsl:with-param name= "commands"
select="*" />
<xsl:with-param name= "x"
2024-05-03 01:59:58 +02:00
select="$initial-x" />
2024-05-06 14:24:53 +02:00
<xsl:with-param name= "y"
select="$initial-y" />
2024-05-06 14:35:12 +02:00
<xsl:with-param name= "angle"
select="$initial-angle" />
2024-05-06 18:26:50 +02:00
<xsl:with-param name= "x-values"
select="$x-values" />
<xsl:with-param name= "y-values"
select="$y-values" />
<xsl:with-param name= "angle-values"
select="$angle-values" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</traceur>
</xsl:template>
2024-05-03 01:50:50 +02:00
2024-05-03 01:59:58 +02:00
<!-- Template récursif pour traiter les commandes individuelles -->
2024-05-06 14:24:53 +02:00
<xsl:template
2024-05-03 01:59:58 +02:00
name="process-commands">
2024-05-06 14:24:53 +02:00
<xsl:param
name="commands" />
<xsl:param
name="x" />
<xsl:param
name="y" />
<xsl:param
2024-05-03 01:59:58 +02:00
name="angle" />
2024-05-06 14:24:53 +02:00
<xsl:param
2024-05-06 18:26:50 +02:00
name="x-values" />
<xsl:param
name="y-values" />
<xsl:param
name="angle-values" />
2024-05-03 01:50:50 +02:00
2024-05-03 01:59:58 +02:00
<!-- Si il reste des commandes à traiter -->
2024-05-06 14:24:53 +02:00
<xsl:if test= "$commands" >
2024-05-03 01:59:58 +02:00
<!-- Sélection de la première commande à traiter -->
2024-05-06 14:24:53 +02:00
<xsl:variable name= "current-command"
select="$commands[1]" />
<xsl:choose >
2024-05-03 01:59:58 +02:00
<!-- Si la commande est une ligne -->
<xsl:when test= "local-name($current-command) = 'line'" >
2024-05-06 14:35:12 +02:00
<!-- Calcul de la distance à parcourir
et conversion de l'angle en radians -->
2024-05-06 14:24:53 +02:00
<xsl:variable name= "distance"
2024-05-03 01:59:58 +02:00
select="number($current-command)" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "radians"
2024-05-03 01:59:58 +02:00
select="$angle * math:pi() div 180" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "new-x"
2024-05-03 01:59:58 +02:00
select="$x + $distance * math:cos($radians)" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "new-y"
2024-05-03 01:59:58 +02:00
select="$y + $distance * math:sin($radians)" />
2024-05-06 14:24:53 +02:00
2024-05-06 14:35:12 +02:00
<!-- Création de l'élément LINETO
avec les nouvelles coordonnées calculées -->
2024-05-06 14:24:53 +02:00
<LINETO
2024-05-03 01:59:58 +02:00
x="{format-number($new-x, '#.######')}"
y="{format-number($new-y, '#.######')}" />
2024-05-06 14:24:53 +02:00
2024-05-06 18:24:07 +02:00
<!-- Appel récursif du template avec la mise à jour
2024-05-06 14:35:12 +02:00
des coordonnées et des commandes restantes -->
2024-05-06 14:24:53 +02:00
<xsl:call-template
2024-05-03 01:59:58 +02:00
name="process-commands">
2024-05-06 14:24:53 +02:00
<xsl:with-param
name="commands" select="$commands[position() > 1]" />
<xsl:with-param
2024-05-03 01:59:58 +02:00
name="x" select="$new-x" />
2024-05-06 14:24:53 +02:00
<xsl:with-param
name="y" select="$new-y" />
<xsl:with-param
2024-05-03 01:59:58 +02:00
name="angle" select="$angle" />
2024-05-06 14:24:53 +02:00
<xsl:with-param
2024-05-06 18:26:50 +02:00
name="x-values" select="$x-values" />
<xsl:with-param
name="y-values" select="$y-values" />
<xsl:with-param
name="angle-values" select="$angle-values" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</xsl:when>
2024-05-06 14:24:53 +02:00
2024-05-03 01:59:58 +02:00
<!-- Si la commande est un turn -->
<xsl:when test= "local-name($current-command) = 'turn'" >
2024-05-06 14:35:12 +02:00
<!-- Calcul du nouvel angle avec modulo 360 pour rester
dans un cercle complet -->
2024-05-06 14:24:53 +02:00
<xsl:variable name= "new-angle"
select="($angle + number($current-command)) mod 360" />
2024-05-06 18:24:07 +02:00
<!-- Appel récursif du template sans changer de
2024-05-06 14:35:12 +02:00
position mais en mettant à jour l'angle -->
2024-05-06 14:24:53 +02:00
<xsl:call-template
2024-05-03 01:59:58 +02:00
name="process-commands">
2024-05-06 18:26:50 +02:00
<xsl:with-param name= "commands"
select="$commands[position() > 1]" />
<xsl:with-param name= "x"
select="$x" />
<xsl:with-param name= "y"
select="$y" />
<xsl:with-param name= "angle"
select="$new-angle" />
<xsl:with-param name= "x-values"
select="$x-values" />
<xsl:with-param name= "y-values"
select="$y-values" />
<xsl:with-param name= "angle-values"
select="$angle-values" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</xsl:when>
2024-05-06 14:24:53 +02:00
2024-05-03 01:59:58 +02:00
<!-- Si la commande est un MOVE -->
<xsl:when test= "local-name($current-command) = 'move'" >
2024-05-06 14:35:12 +02:00
<!-- Calcul de la distance à parcourir et conversion
de l'angle en radians -->
2024-05-06 14:24:53 +02:00
<xsl:variable name= "distance"
2024-05-03 01:59:58 +02:00
select="number($current-command)" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "radians"
2024-05-03 01:59:58 +02:00
select="$angle * math:pi() div 180" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "new-x"
2024-05-03 01:59:58 +02:00
select="$x + $distance * math:cos($radians)" />
2024-05-06 14:24:53 +02:00
<xsl:variable name= "new-y"
2024-05-03 01:59:58 +02:00
select="$y + $distance * math:sin($radians)" />
2024-05-06 14:24:53 +02:00
2024-05-06 14:35:12 +02:00
<!-- Création de l'élément MOVETO avec
les nouvelles coordonnées calculées -->
2024-05-06 14:24:53 +02:00
<MOVETO
2024-05-03 01:59:58 +02:00
x="{format-number($new-x, '#.######')}"
y="{format-number($new-y, '#.######')}" />
2024-05-06 14:24:53 +02:00
2024-05-06 18:24:07 +02:00
<!-- Appel récursif du template avec la mise à jour
2024-05-06 14:35:12 +02:00
des coordonnées et des commandes restantes -->
2024-05-06 18:26:50 +02:00
<xsl:call-template
2024-05-03 01:59:58 +02:00
name="process-commands">
2024-05-06 18:26:50 +02:00
<xsl:with-param name= "commands"
select="$commands[position() > 1]" />
<xsl:with-param name= "x"
select="$new-x" />
<xsl:with-param name= "y"
select="$new-y" />
<xsl:with-param name= "angle"
select="$angle" />
<xsl:with-param name= "x-values"
select="$x-values" />
<xsl:with-param name= "y-values"
select="$y-values" />
<xsl:with-param name= "angle-values"
select="$angle-values" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</xsl:when>
2024-05-06 14:24:53 +02:00
2024-05-03 01:59:58 +02:00
<!-- Si la commande est un store -->
<xsl:when test= "local-name($current-command) = 'store'" >
2024-05-06 18:26:50 +02:00
<xsl:variable name= "new-x-values"
select="($x-values, $x)" />
<xsl:variable name= "new-y-values"
select="($y-values, $y)" />
<xsl:variable name= "new-angle-values"
select="($angle-values, $angle)" />
<!-- Appel récursif -->
<xsl:call-template name= "process-commands" >
2024-05-06 14:35:12 +02:00
<xsl:with-param name= "commands"
select="$commands[position() > 1]" />
<xsl:with-param name= "x"
select="$x" />
<xsl:with-param name= "y"
select="$y" />
<xsl:with-param name= "angle"
select="$angle" />
2024-05-06 18:26:50 +02:00
<xsl:with-param name= "x-values"
select="$new-x-values" />
<xsl:with-param name= "y-values"
select="$new-y-values" />
<xsl:with-param name= "angle-values"
select="$new-angle-values" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</xsl:when>
2024-05-06 18:26:50 +02:00
<!-- Si la commande est un restore -->
<xsl:when test= "local-name($current-command) = 'restore' and count($x-values) > 0" >
<xsl:variable name= "last-x"
select="$x-values[last()]" />
<xsl:variable name= "last-y"
select="$y-values[last()]" />
<xsl:variable name= "last-angle"
select="$angle-values[last()]" />
<!-- Création de l'élément MOVETO -->
<MOVETO
x="{format-number($last-x, '#.######')}"
y="{format-number($last-y, '#.######')}" />
2024-05-06 14:25:30 +02:00
2024-05-06 14:35:12 +02:00
<!-- Appel récursif -->
<xsl:call-template
2024-05-03 01:59:58 +02:00
name="process-commands">
2024-05-06 14:35:12 +02:00
<xsl:with-param name= "commands"
select="$commands[position() > 1]" />
<xsl:with-param name= "x"
2024-05-06 18:26:50 +02:00
select="$last-x" />
2024-05-06 14:24:53 +02:00
<xsl:with-param name= "y"
2024-05-06 18:26:50 +02:00
select="$last-y" />
2024-05-06 14:24:53 +02:00
<xsl:with-param name= "angle"
2024-05-06 18:26:50 +02:00
select="$last-angle" />
<xsl:with-param name= "x-values"
select="subsequence($x-values, 1, count($x-values) - 1)" />
<xsl:with-param name= "y-values"
select="subsequence($y-values, 1, count($y-values) - 1)" />
<xsl:with-param name= "angle-values"
select="subsequence($angle-values, 1, count($angle-values) - 1)" />
2024-05-03 01:59:58 +02:00
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:template>
2024-05-03 01:50:50 +02:00
</xsl:transform>