Diff for /loncom/homework/functionplotresponse.pm between versions 1.31 and 1.75

version 1.31, 2010/11/10 22:41:29 version 1.75, 2011/11/19 13:45:36
Line 1 Line 1
 # LearningOnline Network with CAPA  # LearningOnline Network with CAPA
 # option list style responses  # Functionplot responses
 #  #
 # $Id$  # $Id$
 #  #
Line 31  use strict; Line 31  use strict;
 use Apache::response();  use Apache::response();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::run;
    
 BEGIN {  BEGIN {
   &Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline','functionplotrule'));    &Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline',
                                                               'plotobject','plotvector','functionplotvectorrule',
                                                               'functionplotrule','functionplotruleset',
                                                               'functionplotelements'));
 }  }
   
 #  #
Line 45  sub geogebra_startcode { Line 49  sub geogebra_startcode {
     my ($id)=@_;      my ($id)=@_;
     return (<<ENDSTARTCODE);      return (<<ENDSTARTCODE);
 <applet name="ggbApplet_$id" code="geogebra.GeoGebraApplet" archive="geogebra.jar"  <applet name="ggbApplet_$id" code="geogebra.GeoGebraApplet" archive="geogebra.jar"
          codebase="/adm/geogebra/"  width="714" height="447" MAYSCRIPT>           codebase="/adm/geogebra/"  width="722" height="447" MAYSCRIPT>
        <param name="java_arguments" value="-Xmx512m -Djnlp.packEnabled=true"/>         <param name="java_arguments" value="-Xmx512m -Djnlp.packEnabled=true"/>
 ENDSTARTCODE  ENDSTARTCODE
 }  }
Line 59  sub geogebra_endcode { Line 63  sub geogebra_endcode {
 #  #
 sub geogebra_spline_program {  sub geogebra_spline_program {
     return (<<ENDSPLINEPROGRAM);      return (<<ENDSPLINEPROGRAM);
 <param name="ggbBase64" value="UEsDBBQACAAIADhQET0AAAAAAAAAAAAAAAASAAAAZ2VvZ2VicmFfbWFjcm8ueG1s7Z1bb+PGGYavk19BMDfexkvP+QCsEqzOuWi7gIveBG1By7RXrSwJsqyY+fWdGZLS2pQtzdqWSPoDApOSqCH5vSTnmdH7bj79en8zCVbJ4nY8m7ZCHKEwSKaj2eV4et0K75ZXH1X46y8/frpOZtfJxSIOrmaLm3jZCmlEQvP+TTxazILRzeXf4pukFZ7PJ+NpQsJgOZtNtrw1TCbz9Vu/f8Gn5/j0Czk9J/8Kg/FoNu2PJ+YrYXD7dfbHb9N/mG+040UrXC7ukvXefpvO75ZBjFrh5zCIsVnEZklaYdssqFnE4Vmx7d/vluuNV9nW7VW29ee228zs9NY0P1qa8w+W42W2//hu+XW2sGuX8dK+Y7ZMJslNMl0Gy3Ru3pnPxtNlGEzii2Rij+SXH3/4ZI86mF38Nxkt82MuPr+KJ7eJ3d8Pn8znndlktghM86bY1+7vhfsbT+ZfY7NmRHCbTuI0WQSreGI/zd8xzf11dpk8eDeejo0m9gRul8ncNoBNCedJcpkrmh2yWZmbJp2y3xzQaDZbXN4G962QRBwhKpEginGFJA2DtBWyiDPNJOVYEiwFEmHwZ9au+7orxPn4z/yQqKvqWV6sHWVrN6JsLMIIESqJ4EIiJiXP6yYoUoQIoYggFPHXq5u54l9cOML58UtHIkW4FJJQIqhQQrrK8UhizqRCmHPCNCeveMU1pXIsYlIrIYS57jBhiOWV4+ZdLZCWGEtMsGfl7ueL5NZ2BUU54ov/3Jse4X6erZ7cfwhawQmJUPCX4P7fJzRCH4KPAS1eE/v65wDbhXnj5LN9xd2nJ5vNyaPN7/ONY/OZ+8bJx4d7+PnhHrLN21vbfriJbbH9IQzOSpfF1d3UPfPDB2fqdDN90/kynSTB8ut49L+pKYjRfCPMWekCygQqGnKX01s9s/Y4uJ2CphtBUz9BUx9BUz9B092Cpr6Cpo0TdDS7uYmnl8HUsVXnbrFKOvFimdyO46k72fGajtz9uvyQUY/T2r0w6LPMQMkeaxCzb54Ps29wKcOjs3yHpXKP7K5H612ve6b20yUXz5V8n4ewe/C+WdHFnkX/pzne2eJRsTcoWirk6vlCrrLm1gVcfec1e9BebNMPoYgSTrUQiGGppGbYdUQ4wuYtxJhW1IAk4xk1bna0z/m5vWRb3dq/5qpbX3BZAZbm9RfbqWVPtM/foVw7HxaUlWv7Kdeun3JSC6KphS2sDb1m3IoizbTVjCjFmcJcH0K69mPpzr4dmdnXbkD31JCTloectDzkpN8OOU+/0NNz+roDT/c47ZgFN4v9xqGdVfbtz+3s2+0OjEvL41IimZLIAK151FAN41IYl771uJSbxx8VWFCsGKUwLoVxKYxLYVwK41IYl8K4tB6jGxiXwrj09celz1FcpxHjBoO53CCvMIMGwoSF3WLcYCCOasSxZlRJX4Z7rm5NoV8REcwpNhUiihJRwK+gDJurVjCmEOHspfB7MVrDr131hd/tPPME/OZksy/8dnbDb8e22NmPldyZNo2VtgqabgT1hl8PQVM/QdPdgqa+gr5r+HX3awG/Tmsf+M3nBn3ht915n/DbycrcKSNUxw+hOrVDKGanWhQnhCshCOO0QCgpsNIKGzYWVBF1CITqvGxqn5Wn9ll5ap/9/uWn0/OfTqMoetMp/SAWrbBrFtIs/Gb4u6usMTfTz91t6VrrdGHGH2b8YcYfZvxrWTmY8YcZf5jxhxl/mPGvxKAHZvxhxr9+ysGM/5Fn/IkkBBFlBg7M3CpvPWxo0IQ/VgprpZDGHBeRKR4JZMeuTCGLxkrBjD/M+MOMf3MEhRn/asIvzPhXc8b/ORboNgKhpBHAkpJiBCsm1JvPvHabglAykgafBGdMmCuUSV3MH3IipZaYMso5961cqccdXa4Ryq76ItT2XvEJhMr7x30Rqrsbobq2xe5+Pa4706b1uFsFTTeCeiOUh6Cpn6DpbkFTX0HfNUK5+7VAKKe1D0LlP6/6IlSn+z4RqpuVuVtGqK4fQnVrh1AP5w+pLAiKYM0lYhxLs8Uh+Kn7WDc/xwQvOyZ42THBj+OYCGLVCntmoc3i+wwUvVXWuDNSiNxIId0t61rv9lyzYKgAQwUYKsBQUbfKgaECDBVgqABDBRgqKjEgAkMFGCrqpxwYKsBQUUf4BUMFGCrAUAGGCjBUVAJ+wVABhorjgAAYKsBQAYaKQyIUGCpqLSgYKqqJUGCoqKCh4jkQ6DWCn3SEsZAGk5j5iwghxS/+UnClNULmD5av+Ptrryn8pCNmmFMwxZH9585w8T+lYYxR7C5lpIl+KT5dJmt8squ++LS9R3wCn/K+cV986u3Gp55tsbdfb+vOtGm97VZB042g3vjkIWjqJ2i6W9DUV9B3jU/ufi3wyWntg0+5O80Xn7q994lPvazMvTI+9fzwqVdzfOJM5PykhJSEmcG8wgjjg0xA9R4r5+dIFWVHqig7UkUlHKmmDdNW3y5NY/2XWVT7q2xvzqoqc6uqyq2q2t3V2f56fbcf8KyCZxU8q+BZrVvlwLMKnlXwrIJnFTyrlRg0gWcVPKv1Uw48q+BZrSP8gmcVPKvgWQXPKnhWKwG/4FkFz+pxQAA8q+BZBc/qIREKPKu1FhQ8q9VEKPCsgmf1CBQAnlXwrIJnFTyr4FkFz2qd8Qk8q5X0rD5HAv1GABRGkZTI1FpwTKnBpmICClGJBFGMKySp7y9Rz5WtKQCFcYSlFJgyJDjXhNM3Iajkak1QdtWXoLZ3ik8QVN497ktQ/d0E1bct9vfrcN2ZNq3D3SpouhHUm6A8BE39BE13C5r6CvquCcrdrwVBOa19CCr39/sSVK//Pgmqn5W5Xyaovh9B9WtHUKYDkoxLzgmhTFNW/IanzAdIKs0wUTw3ob8xQfUfK+eX+pHl1I8sp35kNVM/ZsW0NrBL09zgdWJAg1W2fxcHUnkcSOdxIIyKPBB2N352BP2B2zMEgyAYBMEgCAbVrXIQDIJgEASDIBgEwaBKjKsgGATBoPopB8EgCAbVEX4hGATBIAgGQTAIgkGVgF8IBkEw6DggAMEgCAZBMOiQCAXBoFoLCsGgaiIUBIMgGHQECoBgEASDIBgEwSAIBkEwqM74BMEgCAYdBQMgGATBIAgGHZKgIBhUa0EhGFRNgoJgUCWDQc+hwKAZBEUiojRVhp8kR5SJN0eoQWMQikS2ZIJaq6U2/+ECobDEWprRACJ2EPBShrq6XjOUXfVlqO3d4hMMlXeQ+zLUYDdDDWyLg/26XHemTetytwqabgT1ZigPQVM/QdPdgqa+gr5rhnL3a8FQTmsfhsozkr4M1R+8T4YaZGUelBlq4MdQg/ox1AMfFGcFQpnhvbPoMia0OkgGYPBYOL9stSpnq1U5W61qkq02K6a9oV2aBoevG7YerrIDcqFrnYeuMSpS17hIXZMidU3doyE7psHQHQvEryF+DfFriF/XrXIQv4b4NcSvIX4N8etKjLwgfg3x6/opB/FriF/XEX4hfg3xa4hfQ/wa4teVgF+IX0P8+jggAPFriF9D/PqQCAXx61oLCvHraiIUxK8hfn0ECoD4NcSvIX4N8WuIX0P8us74BPFriF8fBQMgfg3xa4hfH5KgIH5da0Ehfl1NgoL4NcSvj8MBEL+G+DXErw/KUBC/rrWgEL+uJkNB/LqK8evnUGDYDISikdCaGVxShlaZRipHKJudZEgyrTizCd7XY6hhYxiKRXg98+T7Q2epY73+uiYlu+pLSts7vydIKe8G9yWl4W5SGtoWh/t1rO5Mm9axbhU03QjqTUoegqZ+gqa7BU19BW06KW3ttIdZpz0sd9pDv057WL9OmyIuiMYYcY40UWvnDZN2Qh5hxjkR7BC99vAFjOuetAXjurvUh3HzfwfEl3EHwwYy7pP/Us3ZdTK7Ti4W8S//B1BLBwhgj4YNdwsAAFgqAQBQSwMEFAAIAAgAOFARPQAAAAAAAAAAAAAAAAwAAABnZW9nZWJyYS54bWytVE2P2jAQPXd/heV7gTgEgpSwareXrVB7YLuH3pxkCC5OHNkOH/vrO7YT2EXqrQdw/Gb8/ObL2eO5keQI2gjV5jSazCiBtlSVaOuc9nb3OaWP64esBlVDoTnZKd1wm9N4wqjDe7F++JSZvToRLr3Lq4BTTndcGqDEdBp4ZfYA9gPO+7OQguvLz+IPlNbcDIHkue16vMXqHrGyqTbCjNupv7CTwn4TR1GBJlKVOV0kKB2/XkFbUXKZ0/ksICyn7M6IUOyse6XFm2qtc7+R7xAhxIg3wIwwh2VTH2gGfSlFJXjrgvE60ImQk6jsPqfLhCEliHqPWpNoFthKpXS1vRgLDTn/Bq3w7iWbLJaLmMX4wz88dgkWlqSTZJGweTRny9UqWWIKUS8KYYtJzFJkZctZki5SluChf9v81XDcgrVYSkP4GcyYz1qL6ppwt3k2X5W8QZ0SrX3ine21b4N4gLb24m7DvGkX45e2ljBgEVZpD+WhUOdtyFscqF8unT/i9RT1k5JKE+0CRf31sBZh9T5O6NVr5n1m3mPgcKRXe7Ri3sOvRVi9lxRtkDYEHo1Rj1XhZ2GIA5Dcde+YG8kLwGagpG+F3YwbbJrDLVLn/6NvCpya921zpYz+E2U2veu37AC6BRm6qsXC9qo35Oi6N5TO66igFA1ug2FICHfF+oUCAlpBrWHUHUYupMtbP3TuHZxNRxFOg0GtpcW3A+OxLpZt51Kfugm3OF05/c4bMGTD8Y2xF0oqbtHLPR3T98f9iA1vzPovUEsHCEyILqxEAgAAlQQAAFBLAQIUABQACAAIADhQET1gj4YNdwsAAFgqAQASAAAAAAAAAAAAAAAAAAAAAABnZW9nZWJyYV9tYWNyby54bWxQSwECFAAUAAgACAA4UBE9TIgurEQCAACVBAAADAAAAAAAAAAAAAAAAAC3CwAAZ2VvZ2VicmEueG1sUEsFBgAAAAACAAIAegAAADUOAAAAAA=="/>  <param name="ggbBase64" value="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"/>
 ENDSPLINEPROGRAM  ENDSPLINEPROGRAM
 }  }
   
Line 72  sub geogebra_default_parameters { Line 76  sub geogebra_default_parameters {
         <param name="image" value="/adm/lonIcons/lonanim.gif"  />          <param name="image" value="/adm/lonIcons/lonanim.gif"  />
         <param name="boxborder" value="false"  />          <param name="boxborder" value="false"  />
         <param name="centerimage" value="true"  />          <param name="centerimage" value="true"  />
         <param name="java_arguments" value="-Xmx512m" />   <param name="cache_archive" value="geogebra.jar, geogebra_main.jar, geogebra_gui.jar, geogebra_cas.jar, geogebra_export.jar, geogebra_algos.jar, geogebra_javascript.jar, geogebra_properties.jar, jlatexmath.jar, jlm_cyrillic.jar, jlm_greek.jar" />
         <param name="cache_archive" value="geogebra.jar, geogebra_main.jar, geogebra_gui.jar, geogebra_cas.jar, geogebra_export.jar, geogebra_properties.jar" />   <param name="cache_version" value="4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0" />
         <param name="cache_version" value="3.2.44.0, 3.2.44.0, 3.2.44.0, 3.2.44.0, 3.2.44.0, 3.2.44.0" />  
         <param name="framePossible" value="false" />          <param name="framePossible" value="false" />
   
         <param name="showResetIcon" value="false" />          <param name="showResetIcon" value="false" />
Line 107  sub init_script { Line 110  sub init_script {
           $script.="if (param=='applet_$id') { loaded_$id=true; }\n";            $script.="if (param=='applet_$id') { loaded_$id=true; }\n";
       }        }
       $script.="if (".join(' && ',map { "loaded_$_" } (@Apache::functionplotresponse::callscripts)).        $script.="if (".join(' && ',map { "loaded_$_" } (@Apache::functionplotresponse::callscripts)).
                ") { setTimeout('ggbInitAll()',20) }";                 ") { setTimeout('ggbInitAll()',200) }";
       my $calls=join("\n",map { "ggbInit_$_();" } (@Apache::functionplotresponse::callscripts));         my $calls=join("\n",map { "ggbInit_$_();" } (@Apache::functionplotresponse::callscripts)); 
       return (<<ENDGGBINIT);        return (<<ENDGGBINIT);
 <script type="text/javascript">  <script type="text/javascript">
Line 157  sub update_register { Line 160  sub update_register {
 }  }
   
 #  #
 # Set a coordinate variable  # Set a point coordinate variable
 #  #
 sub set_coordinate {  sub set_point_coordinate {
    my ($id,$variable,$x,$y)=@_;     my ($id,$variable,$x,$y,$fixed)=@_;
      my $mult=($fixed?'a*':'');
   # Get rid of wild exponents, make sure it's a number
      $x=1.*$x;
      $y=1.*$y;
   # GeoGebra does not understand "E"
      $x=~s/[e|E]/\*10\^/;
      $x=~s/\+//;
      $y=~s/[e|E]/\*10\^/;
      $y=~s/\+//;
    return (<<ENDSETVARIABLE);     return (<<ENDSETVARIABLE);
 document.ggbApplet_$id.evalCommand("$variable=($x,$y)");  document.ggbApplet_$id.evalCommand("a=1");
   document.ggbApplet_$id.evalCommand("$variable=$mult($x,$y)");
   document.ggbApplet_$id.setLabelVisible("$variable",false);
 ENDSETVARIABLE  ENDSETVARIABLE
 }  }
   
 #  #
   # Set a slope coordinate variable
   #
   sub set_slope_coordinate {
      my ($id,$variable,$xrel,$yrel,$xmin,$xmax,$ymin,$ymax,$pointname,$fixed)=@_;
      my $xvariable=$variable.'x';
      my $yvariable=$variable.'y';
      my $domain=$xmax-$xmin;
      my $range=$ymax-$ymin;
      my $xinterval=$domain/100.;
      my $yinterval=$range/200.;
      my $mult=($fixed?'a*':'');
      return (<<ENDSETSVARIABLE);
   document.ggbApplet_$id.evalCommand("a=1");
   document.ggbApplet_$id.evalCommand("$xvariable=Slider[$xinterval,$domain,$xinterval]");
   document.ggbApplet_$id.setVisible("$xvariable", false);
   document.ggbApplet_$id.evalCommand("$xvariable=$xrel");
   document.ggbApplet_$id.evalCommand("$yvariable=Slider[-$range,$range,$yinterval]");
   document.ggbApplet_$id.setVisible("$yvariable", false);
   document.ggbApplet_$id.evalCommand("$yvariable=$yrel");
   document.ggbApplet_$id.evalCommand("$variable=$mult($xvariable+x($pointname),$yvariable+y($pointname))");
   document.ggbApplet_$id.setLabelVisible("$variable", false);
   ENDSETSVARIABLE
   }
   
   #
 # Input field name for a coordinate variable  # Input field name for a coordinate variable
 #  #
   
Line 187  sub generate_input_field { Line 226  sub generate_input_field {
 }  }
   
 #  #
 # Initialize a new coordinate variable at set a listener on it  # Initialize a new point coordinate variable at set a listener on it
   #
   sub new_point_coordinate {
       my ($id,$variable,$x,$y,$fixed)=@_;
       if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'x')})) {
          $x=$Apache::functionplotresponse::previous{&field_name($id,$variable,'x')};
       }
       if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'y')})) {
          $y=$Apache::functionplotresponse::previous{&field_name($id,$variable,'y')};
       }
       &generate_input_field($id,$variable,$x,$y);
       return &set_point_coordinate($id,$variable,$x,$y,$fixed).&update_register($id,$variable);
   }
   
   #
   # Initialize a new slope coordinate variable at set a listener on it
   #
   sub new_slope_coordinate {
       my ($id,$variable,$x,$y,$pointname,$xp,$yp,$xmin,$xmax,$ymin,$ymax,$fixed)=@_;
   #
   # $variable: name of the slope point
   # $x, $y: coordinates of the slope point
   # $pointname: name of the associated point point
   # $xp $yp: coordinates of the point point
 #  #
 sub new_coordinate {  
     my ($id,$variable,$x,$y)=@_;  
     if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'x')})) {      if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'x')})) {
        $x=$Apache::functionplotresponse::previous{&field_name($id,$variable,'x')};         $x=$Apache::functionplotresponse::previous{&field_name($id,$variable,'x')};
     }      }
     if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'y')})) {      if (defined($Apache::functionplotresponse::previous{&field_name($id,$variable,'y')})) {
        $y=$Apache::functionplotresponse::previous{&field_name($id,$variable,'y')};         $y=$Apache::functionplotresponse::previous{&field_name($id,$variable,'y')};
     }      }
       if (defined($Apache::functionplotresponse::previous{&field_name($id,$pointname,'x')})) {
          $xp=$Apache::functionplotresponse::previous{&field_name($id,$pointname,'x')};
       }
       if (defined($Apache::functionplotresponse::previous{&field_name($id,$pointname,'y')})) {
          $yp=$Apache::functionplotresponse::previous{&field_name($id,$pointname,'y')};
       }
   
     &generate_input_field($id,$variable,$x,$y);      &generate_input_field($id,$variable,$x,$y);
     return &set_coordinate($id,$variable,$x,$y).&update_register($id,$variable);      my $xrel=$x-$xp;
       my $yrel=$y-$yp;
       return &set_slope_coordinate($id,$variable,$xrel,$yrel,$xmin,$xmax,$ymin,$ymax,$pointname,$fixed).&update_register($id,$variable);
 }  }
   
 #  #
Line 240  ENDAXESSCRIPT Line 309  ENDAXESSCRIPT
 }  }
   
 sub axes_label {  sub axes_label {
     my ($id,$xlabel,$ylabel)=@_;      my ($id,$xmin,$xmax,$ymin,$ymax,$xlabel,$ylabel)=@_;
     unless ($xlabel || $ylabel) { return ''; }      unless ($xlabel || $ylabel) { return ''; }
     my $return='document.ggbApplet_'.$id.'.evalCommand("topRight=Corner[3]");';      my $return='document.ggbApplet_'.$id.'.evalCommand("topRight=Corner[3]");';
     if ($xlabel) {      if ($xlabel) {
         if (($ymin<0) && ($ymax>0)) {
        $return.=(<<ENDXAXISLABELSCRIPT);         $return.=(<<ENDXAXISLABELSCRIPT);
 document.ggbApplet_$id.evalCommand("Xlabel=(x(topRight)-AxisStepX[],AxisStepY[]/6)");  document.ggbApplet_$id.evalCommand("Xlabel=(x(topRight)-AxisStepX[],AxisStepY[]/6)");
 document.ggbApplet_$id.setVisible("Xlabel",false);  document.ggbApplet_$id.setVisible("Xlabel",false);
 document.ggbApplet_$id.evalCommand("Text[\\"$xlabel\\", Xlabel]");  document.ggbApplet_$id.evalCommand("Text[\\"$xlabel\\", Xlabel]");
 ENDXAXISLABELSCRIPT  ENDXAXISLABELSCRIPT
         } else {
          $return.=(<<ENDXOFFAXISLABEL);
   document.ggbApplet_$id.evalCommand("LowerRight=Corner[2]");
   document.ggbApplet_$id.evalCommand("Text[\\"$xlabel\\", (x(LowerRight) - AxisStepX[], y(LowerRight) + AxisStepY[] / 2)]");
   ENDXOFFAXISLABEL
         }
     }      }
     if ($ylabel) {      if ($ylabel) {
         if (($xmin<0) && ($xmax>0)) {
        $return.=(<<ENDYAXISLABELSCRIPT);         $return.=(<<ENDYAXISLABELSCRIPT);
 document.ggbApplet_$id.evalCommand("Ylabel=(AxisStepX[]/6,y(topRight)-AxisStepY[]/3)");  document.ggbApplet_$id.evalCommand("Ylabel=(AxisStepX[]/6,y(topRight)-AxisStepY[]/3)");
 document.ggbApplet_$id.setVisible("Ylabel",false);  document.ggbApplet_$id.setVisible("Ylabel",false);
 document.ggbApplet_$id.evalCommand("Text[\\"$ylabel\\", Ylabel]");  document.ggbApplet_$id.evalCommand("Text[\\"$ylabel\\", Ylabel]");
 ENDYAXISLABELSCRIPT  ENDYAXISLABELSCRIPT
         } else {
          $return.=(<<ENDYOFFAXISLABEL);
   document.ggbApplet_$id.evalCommand("UpperLeft=Corner[4]");
   document.ggbApplet_$id.evalCommand("Text[\\"$ylabel\\", (x(UpperLeft) + AxisStepX[] / 5, y(UpperLeft) - AxisStepY[] / 1.8)]");
   ENDYOFFAXISLABEL
         }
     }      }
     return $return;      return $return;
 }  }
   
   #
   # Subroutine to produce background and answer plots
   #
   
 sub plot_script {  sub plot_script {
    my ($id,$function,$fixed)=@_;     my ($id,$function,$fixed,$label,$color,$xmin,$xmax,$thickness)=@_;
      $label=~s/\W//g;
      if (($label) && ($label!~/^[A-Za-z]/)) {
         $label='C'.$label;
      }
      my $visible=0;
      if ($label) {
         $visible="1";
      } else {
         $Apache::functionplotresponse::counter++;
         $label='C'.$Apache::functionplotresponse::counter;
      }
      my $rc=0;
      my $gc=0;
      my $bc=0;
      if ($color) {
         my ($rh,$gh,$bh)=($color=~/(..)(..)(..)/);
         $rc=hex($rh);
         $gc=hex($gh);
         $bc=hex($bh);
      }
    if ($fixed) {     if ($fixed) {
 # Use stupid trick to nail this to a location        return "document.ggbApplet_$id.evalCommand('$label=Function[$function,$xmin,$xmax]');\n".
 # Oddly, it seems like only one plot cannot be nailed to a location               ($visible?'':"document.ggbApplet_$id.setLabelVisible('$label', false);\n").
 # Non-nailed-down plots apparently get overwritten               ($color?"document.ggbApplet_$id.setColor('$label',$rc,$gc,$bc);\n":'').
       return (<<ENDPLOTSCRIPT);               ($thickness?"document.ggbApplet_$id.setLineThickness('$label',$thickness);\n":'');
             document.ggbApplet_$id.evalCommand("a=1");  
             document.ggbApplet_$id.setVisible("a",false);  
             // This MUST be a DEPENDENT OBJECT in order to be locked down:  
             document.ggbApplet_$id.evalCommand("y=a*($function)");  
 ENDPLOTSCRIPT  
    } else {     } else {
        return "document.ggbApplet_$id.evalCommand('y=$function')";         return "document.ggbApplet_$id.evalCommand('y=$function');\n";
    }     }
 }  }
   
 #  #
   # Subroutine to produce objects
   #
   
   sub plotobject_script {
      my ($id,$label,$x,$y)=@_;
      unless ($label) {
         $Apache::functionplotresponse::counter++;
         $label='O'.$Apache::functionplotresponse::counter;
      }
      return "document.ggbApplet_$id.evalCommand('a=1');\n".
             "document.ggbApplet_$id.setVisible('a', false);\n".
             "document.ggbApplet_$id.setLabelVisible('a', false);\n".
             "document.ggbApplet_$id.evalCommand('$label=a*($x,$y)');\n".
             "document.ggbApplet_$id.setVisible('$label', true);\n".
             "document.ggbApplet_$id.setLabelVisible('$label', true);\n";
   }
   
   #
   # Subroutine to produce vectors
   #
   
   sub plotvector_script {
      my ($id,$label,$xs,$ys,$xe,$ye,$xmin,$xmax)=@_;
      unless ($label) {
         $Apache::functionplotresponse::counter++;
         $label='V'.$Apache::functionplotresponse::counter;
      }
      my $startlabel=$label.'Start';
      my $endlabel=$label.'End';
      my $pointlabel=$label.'Point';
      my $pointx=2.*($xmax-$xmin)+$xmax;
      my $anglelabel=$label.'Angle';
      return 
          &new_point_coordinate($id,$startlabel,$xs,$ys,0).
          &new_point_coordinate($id,$endlabel,$xe,$ye,0).
          (<<ENDVECTOR);
   document.ggbApplet_$id.evalCommand("$label=Vector[$startlabel,$endlabel]");
   document.ggbApplet_$id.setLabelVisible("$label",true);
   document.ggbApplet_$id.setLineThickness("$label",8);
   document.ggbApplet_$id.evalCommand("$pointlabel=($pointx,y($startlabel))");
   document.ggbApplet_$id.evalCommand("$anglelabel=Angle[$pointlabel,$startlabel,$endlabel]");
   document.ggbApplet_$id.setLabelVisible("$anglelabel",true);
   document.ggbApplet_$id.setLabelStyle("$anglelabel",VALUE=2);
   ENDVECTOR
   }
   
   #
   # Answer spline display
   # 
   # points: x,y,slope_x,slope_y
   
   sub answer_spline_script {
      my ($id,@points)=@_;
      my $order=int(($#points+1)/4);
      if ($order<2) { $order=2; }
      if ($order>8) { $order=8; }
      $Apache::functionplotresponse::counter++;
      my $label='CSpline'.$Apache::functionplotresponse::counter;
      my $output='document.ggbApplet_'.$id.'.evalCommand("'.$label.'=Spline'.$order.'[';
      for (my $i=0;$i<=$#points;$i+=4) {
         $output.="($points[$i],$points[$i+1]),($points[$i+2],$points[$i+3]),";
      }
      $output=~s/\,$//;
      $output.=']");'."\n";
      for (my $i=2; $i<2*$order; $i+=2) {
          $output.='document.ggbApplet_'.$id.'.setColor("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",0,170,0);'."\n";
      }
      for (my $i=1; $i<2*$order; $i+=2) {
          $output.='document.ggbApplet_'.$id.'.setVisible("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",false);'."\n";
      }
   
      return $output;
   }
   
   #
 # Subroutine that generates code for spline $label based on stored information  # Subroutine that generates code for spline $label based on stored information
 #  #
   
 sub generate_spline {  sub generate_spline {
    my ($id,$label)=@_;     my ($id,$label,$xmin,$xmax,$ymin,$ymax,$fixed)=@_;
    my $result='';     my $result='';
    my $order=$Apache::functionplotresponse::splineorder{$label};     my $order=$Apache::functionplotresponse::splineorder{$label};
    my $x=$Apache::functionplotresponse::splineinitx{$label};     my $x=$Apache::functionplotresponse::splineinitx{$label};
Line 291  sub generate_spline { Line 468  sub generate_spline {
    my $sy=$Apache::functionplotresponse::splinescaley{$label};     my $sy=$Apache::functionplotresponse::splinescaley{$label};
    my @coords=();     my @coords=();
    foreach my $i (1..$order) {     foreach my $i (1..$order) {
        $result.=&new_coordinate($id,$label.'P'.$i,$x,$y);         $result.=&new_point_coordinate($id,$label.'P'.$i,$x,$y,$fixed);
          my $xp=$x;
        $x+=$sx/(2.*($order-1));         $x+=$sx/(2.*($order-1));
        push(@coords,$label.'P'.$i);         push(@coords,$label.'P'.$i);
        $result.=&new_coordinate($id,$label.'S'.$i,$x,$y+$sy);         $result.=&new_slope_coordinate($id,$label.'S'.$i,$x,$y+$sy,$label.'P'.$i,$xp,$y,$xmin,$xmax,$ymin,$ymax,$fixed);
        $x+=$sx/(2.*($order-1));         $x+=$sx/(2.*($order-1));
        push(@coords,$label.'S'.$i);         push(@coords,$label.'S'.$i);
    }     }
    $result.='document.ggbApplet_'.$id.'.evalCommand("Spline'.$order.'['.join(',',@coords).']");'."\n";     $result.='document.ggbApplet_'.$id.'.evalCommand("Spline'.$order.'['.join(',',@coords).']");'."\n";
    return $result;     return $result;
 }  }
   
   #
   # Object
   #
   
   sub start_plotobject {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1];
      my $x=&Apache::lonxml::get_param('x',$parstack,$safeeval);
      my $y=&Apache::lonxml::get_param('y',$parstack,$safeeval);
      my $label=&Apache::lonxml::get_param('label',$parstack,$safeeval);
      $label=~s/\W//gs;
      $label=ucfirst($label);
      unless ($label) { $label="NewObject"; }
      if ($target eq 'web') {
         my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-3);
         unless (defined($x)) { $x=$xmin; }
         unless (defined($y)) { $y=$ymin; }
         $result.=&plotobject_script($internalid,$label,$x,$y);
      } elsif ($target eq 'edit') {
           $result=&Apache::edit::tag_start($target,$token,'Plot Object').
                &Apache::edit::text_arg('Label on Plot:','label',
                                        $token,'16').
                &Apache::edit::text_arg('x:','x',
                                        $token,'8').
                &Apache::edit::text_arg('y:','y',
                                        $token,'8').
                &Apache::edit::end_row();
     } elsif ($target eq 'modified') {
       $env{'form.'.&Apache::edit::html_element_name('label')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('label')});
       my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,'label','x','y');
       if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
     }
     return $result;
   }
   
   sub end_plotobject {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      if ($target eq 'edit') {
          $result=&Apache::edit::end_table();
      }
      return $result;
   }
   
   #
   # Vector
   #
   
   sub start_plotvector {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1];
      my $tailx=&Apache::lonxml::get_param('tailx',$parstack,$safeeval);
      my $taily=&Apache::lonxml::get_param('taily',$parstack,$safeeval);
      my $tipx=&Apache::lonxml::get_param('tipx',$parstack,$safeeval);
      my $tipy=&Apache::lonxml::get_param('tipy',$parstack,$safeeval);
   
      my $label=&Apache::lonxml::get_param('label',$parstack,$safeeval);
      $label=~s/\W//gs;
      $label=ucfirst($label);
      unless ($label) { $label="NewVector"; }
      if ($target eq 'web') {
         my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-3);
         unless (defined($tailx)) { $tailx=$xmin; }
         unless (defined($taily)) { $taily=$ymin; }
         unless (defined($tipx)) { $tipx=$xmin; }
         unless (defined($tipy)) { $tipy=$ymin; }
         $result.=&plotvector_script($internalid,$label,$tailx,$taily,$tipx,$tipy,$xmin,$xmax);
      } elsif ($target eq 'edit') {
           $result=&Apache::edit::tag_start($target,$token,'Plot Vector').
                &Apache::edit::text_arg('Label on Plot:','label',
                                        $token,'16').
                &Apache::edit::text_arg('Tail x:','tailx',
                                        $token,'8').
                &Apache::edit::text_arg('Tail y:','taily',
                                        $token,'8').
                &Apache::edit::text_arg('Tip x:','tipx',
                                        $token,'8').
                &Apache::edit::text_arg('Tip y:','tipy',
                                        $token,'8').
   
                &Apache::edit::end_row();
     } elsif ($target eq 'modified') {
       $env{'form.'.&Apache::edit::html_element_name('label')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('label')});
       my $constructtag=&Apache::edit::get_new_args($token,$parstack,$safeeval,'label','tailx','taily','tipx','tipy');
       if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
     }
     return $result;
   }
   
   sub end_plotvector {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      if ($target eq 'edit') {
          $result=&Apache::edit::end_table();
      }
      return $result;
   }
   
   
   
 #  #
 # <backgroundplot function="..." fixed="yes/no" />  # <backgroundplot function="..." fixed="yes/no" />
 #  #
Line 309  sub start_backgroundplot { Line 590  sub start_backgroundplot {
    my $result='';     my $result='';
    my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1];     my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1];
    my $function=&Apache::lonxml::get_param('function',$parstack,$safeeval);     my $function=&Apache::lonxml::get_param('function',$parstack,$safeeval);
      my $xinitial=&Apache::lonxml::get_param('xinitial',$parstack,$safeeval);
      my $xfinal=&Apache::lonxml::get_param('xfinal',$parstack,$safeeval);
      my $label=&Apache::lonxml::get_param('label',$parstack,$safeeval);
      my $color=&Apache::lonxml::get_param('color',$parstack,$safeeval);
      $color=~s/[^a-fA-F0-9]//gs;
      unless (length($color)==6) { $color=''; }
    my $fixed=(&Apache::lonxml::get_param('fixed',$parstack,$safeeval)=~/on|true|yes|1/i?1:0);     my $fixed=(&Apache::lonxml::get_param('fixed',$parstack,$safeeval)=~/on|true|yes|1/i?1:0);
     
    unless ($function) { $function="0"; }     unless ($function) { $function="0"; }
    if ($target eq 'web') {     if ($target eq 'web') {
       $result.=&plot_script($internalid,$function,$fixed);        my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-3);
         unless (defined($xinitial)) { $xinitial=$xmin; }
         unless (defined($xfinal)) { $xfinal=$xmax; }
         $result.=&plot_script($internalid,$function,$fixed,$label,$color,$xinitial,$xfinal);
    } elsif ($target eq 'edit') {     } elsif ($target eq 'edit') {
         $result=&Apache::edit::tag_start($target,$token,'Background Function Plot').          $result=&Apache::edit::tag_start($target,$token,'Background Function Plot').
              &Apache::edit::text_arg('Function:','function',               &Apache::edit::text_arg('Function:','function',
                                      $token,'16').                                       $token,'16').
                &Apache::edit::text_arg('Initial x-value (optional):','xinitial',
                                        $token,'8').
                &Apache::edit::text_arg('Final x-value (optional):','xfinal',
                                        $token,'8').
                &Apache::edit::text_arg('Label on Plot:','label',
                                        $token,'8').
                &Apache::edit::text_arg('Color (hex code):','color',
                                        $token,'8').
              &Apache::edit::select_arg('Fixed location:','fixed',               &Apache::edit::select_arg('Fixed location:','fixed',
                                   ['yes','no'],$token).                                    ['yes','no'],$token).
              &Apache::edit::end_row();               &Apache::edit::end_row();
   } elsif ($target eq 'modified') {    } elsif ($target eq 'modified') {
     my $constructtag=&Apache::edit::get_new_args($token,$parstack,      my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                                                  $safeeval,'function','fixed');                                                   $safeeval,'function','label','xinitial','xfinal','color','fixed');
     if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }      if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
   }    }
   return $result;    return $result;
Line 376  sub start_functionplotrule { Line 674  sub start_functionplotrule {
           &Apache::lonxml::warning(&mt('Rule relationship not defined.'));            &Apache::lonxml::warning(&mt('Rule relationship not defined.'));
           $relationship='eq';            $relationship='eq';
       }        }
       my $derivative=&Apache::lonxml::get_param('derivative',$parstack,$safeeval);        my $derivative=&Apache::lonxml::get_param('derivativeorder',$parstack,$safeeval);
       unless (($derivative==0) || ($derivative==1) || ($derivative==2)) {        unless (($derivative==-1) || ($derivative==0) || ($derivative==1) || ($derivative==2)) {
          &Apache::lonxml::warning(&mt('Rule derivative not defined.'));           &Apache::lonxml::warning(&mt('Rule derivative not defined.'));
          $derivative=0;           $derivative=0;
       }        }
Line 388  sub start_functionplotrule { Line 686  sub start_functionplotrule {
            $beginninglabel,             $beginninglabel,
            &Apache::lonxml::get_param('xfinal',$parstack,$safeeval),             &Apache::lonxml::get_param('xfinal',$parstack,$safeeval),
            $endinglabel,             $endinglabel,
              &Apache::lonxml::get_param('minimumlength',$parstack,$safeeval),
              &Apache::lonxml::get_param('maximumlength',$parstack,$safeeval),
            $relationship,             $relationship,
            &Apache::lonxml::get_param('value',$parstack,$safeeval)             &Apache::lonxml::get_param('value',$parstack,$safeeval),
              &Apache::lonxml::get_param('percenterror',$parstack,$safeeval)
           )));            )));
    } elsif ($target eq 'edit') {     } elsif ($target eq 'edit') {
         $result=&Apache::edit::tag_start($target,$token,'Function Plot Evaluation Rule').          $result=&Apache::edit::tag_start($target,$token,'Function Plot Graph Rule').
              &Apache::edit::text_arg('Index:','index',               &Apache::edit::text_arg('Index/Name:','index',
                                      $token,'4').'&nbsp;'.                                       $token,'10').'&nbsp;'.
              &Apache::edit::select_arg(&mt('Function:'),'derivative',               &Apache::edit::select_arg(&mt('Function:'),'derivativeorder',
                                   [['0','Function itself'],                                    [['0','Function itself'],
                                    ['1','First derivative'],                                     ['1','First derivative'],
                                    ['2','Second derivative']],$token).'&nbsp;'.                                     ['2','Second derivative'],
                                      ['-1','Integral']],$token).'<br />'.
              &Apache::edit::text_arg('(Initial) x-value:','xinitial',               &Apache::edit::text_arg('Initial x-value:','xinitial',
                                       $token,'4').                                        $token,'8').
              &Apache::edit::select_or_text_arg('(Initial) x-value label:','xinitiallabel',               &Apache::edit::select_or_text_arg('Initial x-value label:','xinitiallabel',
                                                [['start','Start of Plot']],$token,'8').'&nbsp;'.                                                 [['start','Start of Plot'],
                                                   ['end','End of Plot']],$token,'8').'<br />'.
              &Apache::edit::text_arg('Optional final x-value for ranges:','xfinal',  
                                       $token,'4').               &Apache::edit::text_arg('Final x-value (optional):','xfinal',
              &Apache::edit::select_or_text_arg('Optional final x-value label:','xfinallabel',                                        $token,'8').
                                                [['end','End of Plot']],$token,'8').'&nbsp;'.               &Apache::edit::select_or_text_arg('Final x-value label (optional):','xfinallabel',
                                                  [['end','End of Plot']],$token,'8').'<br />'.
              &Apache::edit::select_arg(&mt('Relationship:'),'relationship',               &Apache::edit::text_arg('Minimum length for range (optional):','minimumlength',
                                        $token,'8').
                &Apache::edit::text_arg('Maximum length for range (optional):','maximumlength',
                                        $token,'8').'<br />'.
                &Apache::edit::select_or_text_arg(&mt('Relationship:'),'relationship',
                                   [['eq','equal'],                                    [['eq','equal'],
                                    ['ne','not equal'],                                     ['ne','not equal'],
                                    ['ge','greater than or equal'],                                     ['ge','greater than or equal'],
Line 418  sub start_functionplotrule { Line 723  sub start_functionplotrule {
                                    ['lt','less than'],                                     ['lt','less than'],
                                    ['le','less than or equal']],$token).                                     ['le','less than or equal']],$token).
              $result.= &Apache::edit::select_or_text_arg('Value:','value',               $result.= &Apache::edit::select_or_text_arg('Value:','value',
                                                [['undef','not defined']],$token,'4').                                                 [['undef','not defined']],$token,'30').
              &Apache::edit::text_arg('Percent error:','percenterror',               &Apache::edit::text_arg('Percent error:','percenterror',
                                      $token,'4').                                       $token,'8').
              &Apache::edit::end_row();               &Apache::edit::end_row();
   } elsif ($target eq 'modified') {    } elsif ($target eq 'modified') {
       if (($env{'form.'.&Apache::edit::html_element_name('xinitial')} ne '') && ($env{'form.'.&Apache::edit::html_element_name('xinitiallabel')} eq 'start')) {
          $env{'form.'.&Apache::edit::html_element_name('xinitiallabel')}='';
       }
       if (($env{'form.'.&Apache::edit::html_element_name('xfinal')} ne '') && ($env{'form.'.&Apache::edit::html_element_name('xfinallabel')} eq 'end')) {
          $env{'form.'.&Apache::edit::html_element_name('xfinallabel')}='';
       }
     my $constructtag=&Apache::edit::get_new_args($token,$parstack,      my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                                                  $safeeval,'index','derivative','xinitial','xinitiallabel','xfinal','xfinallabel','relationship',                                                   $safeeval,'index','derivativeorder',
                                                            'value','percenterror');                                                             'xinitial','xinitiallabel','xfinal','xfinallabel',
                                                              'minimumlength','maximumlength',
                                                              'relationship','value','percenterror');
     if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }      if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
    }     }
    return $result;     return $result;
Line 442  sub end_functionplotrule { Line 755  sub end_functionplotrule {
   
   
 #  #
   # <functionplotvectorrule ... />
   #
   sub start_functionplotvectorrule {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      my $label=&Apache::lonxml::get_param('index',$parstack,$safeeval);
      $Apache::functionplotresponse::counter++;
      if ($label=~/\W/) {
         &Apache::lonxml::warning(&mt('Rule indices should only contain alphanumeric characters.'));
      }
      $label=~s/\W//gs;
      unless ($label) {
         $label='V'.$Apache::functionplotresponse::counter;
      } else {
         $label='V'.$label;
      }
      if ($Apache::functionplotresponse::splineorder{$label}) {
          &Apache::lonxml::error(&mt('Rule indices must be unique.'));
      }
   
      if ($target eq 'grade') {
   # Simply remember - in order - for later
         my $vector=&Apache::lonxml::get_param('vector',$parstack,$safeeval);
         $vector=~s/\W//gs;
         $vector=ucfirst($vector);
         my $tailpoint=&Apache::lonxml::get_param('tailpoint',$parstack,$safeeval);
         $tailpoint=~s/\W//gs;
         $tailpoint=ucfirst($tailpoint);
         my $tippoint=&Apache::lonxml::get_param('tippoint',$parstack,$safeeval);
         $tippoint=~s/\W//gs;
         $tippoint=ucfirst($tippoint);
   
         my $nottailpoint=&Apache::lonxml::get_param('nottailpoint',$parstack,$safeeval);
         $nottailpoint=~s/\W//gs;
         $nottailpoint=ucfirst($nottailpoint);
         my $nottippoint=&Apache::lonxml::get_param('nottippoint',$parstack,$safeeval);
         $nottippoint=~s/\W//gs;
         $nottippoint=ucfirst($nottippoint);
   
         push(@Apache::functionplotresponse::functionplotvectorrules,join(':',(
              $label,
              $vector,
              $tailpoint,
              $tippoint,
              $nottailpoint,
              $nottippoint,
              &Apache::lonxml::get_param('length',$parstack,$safeeval),
              &Apache::lonxml::get_param('angle',$parstack,$safeeval),
              &Apache::lonxml::get_param('lengthpercenterror',$parstack,$safeeval),
              &Apache::lonxml::get_param('anglepercenterror',$parstack,$safeeval),
             )));
      } elsif ($target eq 'edit') {
           $result=&Apache::edit::tag_start($target,$token,'Function Plot Vector Rule').
                &Apache::edit::text_arg('Index/Name:','index',
                                        $token,'10').'&nbsp;'.
                &Apache::edit::text_arg('Vector:','vector',
                                         $token,'16').'<br />'.
                &Apache::edit::text_arg('Tail attached to object:','tailpoint',
                                         $token,'16').
                &Apache::edit::text_arg('Tip attached to object:','tippoint',
                                         $token,'16').
                &Apache::edit::text_arg('Tail not attached to object:','nottailpoint',
                                         $token,'16').
                &Apache::edit::text_arg('Tip not attached to object:','nottippoint',
                                         $token,'16').'<br />'.
                &Apache::edit::text_arg('Length:','length',
                                        $token,'16').
                &Apache::edit::text_arg('Angle:','angle',
                                        $token,'16').
                &Apache::edit::text_arg('Percent error length:','lengthpercenterror',
                                        $token,'8').
                &Apache::edit::text_arg('Percent error angle:','anglepercenterror',
                                        $token,'8').
                &Apache::edit::end_row();
     } elsif ($target eq 'modified') {
       $env{'form.'.&Apache::edit::html_element_name('vector')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('vector')});
       $env{'form.'.&Apache::edit::html_element_name('tailpoint')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('tailpoint')});
       $env{'form.'.&Apache::edit::html_element_name('tippoint')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('tippoint')});
       $env{'form.'.&Apache::edit::html_element_name('nottailpoint')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('nottailpoint')});
       $env{'form.'.&Apache::edit::html_element_name('nottippoint')}=lcfirst($env{'form.'.&Apache::edit::html_element_name('nottippoint')});
       my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                                                    $safeeval,'index','vector',
                                                              'tailpoint','tippoint','nottailpoint','nottipoint',
                                                              'length','angle',
                                                              'lengthpercenterror','anglepercenterror');
       if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
      }
      return $result;
   }
   
   sub end_functionplotvectorrule {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      if ($target eq 'edit') {
          $result=&Apache::edit::end_table();
      }
      return $result;
   }
   
   
   
   #
 # <spline index="..." order="1,2,3,4" initx="..." inity="..." scalex="..." scaley="..." />  # <spline index="..." order="1,2,3,4" initx="..." inity="..." scalex="..." scaley="..." />
 #  #
 # Unfortunately, GeoGebra seems to want all splines after everything else, so we need to store them  # Unfortunately, GeoGebra seems to want all splines after everything else, so we need to store them
Line 490  sub start_spline { Line 905  sub start_spline {
              &Apache::edit::text_arg('Index:','index',               &Apache::edit::text_arg('Index:','index',
                                      $token,'4').'&nbsp;'.                                       $token,'4').'&nbsp;'.
              &Apache::edit::select_arg('Order:','order',               &Apache::edit::select_arg('Order:','order',
                                   ['2','3','4','5','6','7','8','9'],$token).'&nbsp;'.                                    ['2','3','4','5','6','7','8'],$token).'&nbsp;'.
              &Apache::edit::text_arg('Initial x-value:','initx',               &Apache::edit::text_arg('Initial x-value:','initx',
                                      $token,'4').'&nbsp;'.                                       $token,'4').'&nbsp;'.
              &Apache::edit::text_arg('Initial y-value:','inity',               &Apache::edit::text_arg('Initial y-value:','inity',
Line 557  sub get_answer_from_form_fields { Line 972  sub get_answer_from_form_fields {
   
 sub cubic_hermite {  sub cubic_hermite {
    my ($t,$p1,$s1,$p2,$s2)=@_;     my ($t,$p1,$s1,$p2,$s2)=@_;
    return (2.*$t*$t*$t-3.*$t*$t+1.)*$p1 + 5.*($t*$t*$t-2.*$t*$t+$t)*($s1-$p1)+     return (2.*$t*$t*$t-3.*$t*$t+1.)*$p1 + 3.*($t*$t*$t-2.*$t*$t+$t)*($s1-$p1)+
           (-2.*$t*$t*$t+3.*$t*$t)  *$p2 + 5.*($t*$t*$t-$t*$t)      *($s2-$p2);            (-2.*$t*$t*$t+3.*$t*$t)  *$p2 + 3.*($t*$t*$t-$t*$t)      *($s2-$p2);
 }  }
   
 #  #
Line 567  sub cubic_hermite { Line 982  sub cubic_hermite {
   
 sub ddt_cubic_hermite {  sub ddt_cubic_hermite {
    my ($t,$p1,$s1,$p2,$s2)=@_;     my ($t,$p1,$s1,$p2,$s2)=@_;
    return (6.*$t*$t-6.*$t) *$p1 + 5.*(3.*$t*$t-4.*$t+1.)*($s1-$p1)+     return (6.*$t*$t-6.*$t) *$p1 + 3.*(3.*$t*$t-4.*$t+1.)*($s1-$p1)+
           (-6.*$t*$t+6.*$t)*$p2 + 5.*(3.*$t*$t-2.*$t)   *($s2-$p2);            (-6.*$t*$t+6.*$t)*$p2 + 3.*(3.*$t*$t-2.*$t)   *($s2-$p2);
 }  }
   
 #  #
Line 577  sub ddt_cubic_hermite { Line 992  sub ddt_cubic_hermite {
   
 sub d2dt2_cubic_hermite {  sub d2dt2_cubic_hermite {
    my ($t,$p1,$s1,$p2,$s2)=@_;     my ($t,$p1,$s1,$p2,$s2)=@_;
    return (12.*$t-6.) *$p1 + 5.*(6.*$t-4.)*($s1-$p1)+     return (12.*$t-6.) *$p1 + 3.*(6.*$t-4.)*($s1-$p1)+
           (-12.*$t+6.)*$p2 + 5.*(6.*$t-2.)*($s2-$p2);            (-12.*$t+6.)*$p2 + 3.*(6.*$t-2.)*($s2-$p2);
 }  }
   
 #  #
Line 586  sub d2dt2_cubic_hermite { Line 1001  sub d2dt2_cubic_hermite {
 #  #
 sub array_index {  sub array_index {
    my ($xmin,$xmax,$x)=@_;     my ($xmin,$xmax,$x)=@_;
    return int(($x-$xmin)/($xmax-$xmin)*400.+0.5);     if ($x ne '') {
         return int(($x-$xmin)/($xmax-$xmin)*400.+0.5);
      } else {
         return undef;
      }
 }  }
   
 #  #
Line 594  sub array_index { Line 1013  sub array_index {
 #  #
   
 sub populate_arrays {  sub populate_arrays {
     my ($id,$xmin,$xmax)=@_;      my ($id,$xmin,$xmax,$ymin,$ymax)=@_;
     for (my $i=0; $i<=400; $i++) {      for (my $i=0; $i<=400; $i++) {
          $Apache::functionplotresponse::actualxval[$i]=undef;
        $Apache::functionplotresponse::func[$i]=undef;         $Apache::functionplotresponse::func[$i]=undef;
        $Apache::functionplotresponse::dfuncdx[$i]=undef;         $Apache::functionplotresponse::dfuncdx[$i]=undef;
        $Apache::functionplotresponse::d2funcd2x[$i]=undef;         $Apache::functionplotresponse::d2funcd2x[$i]=undef;
Line 617  sub populate_arrays { Line 1037  sub populate_arrays {
                         $env{'form.HWVAL_'.$id.'_'.$label.'S'.$ni.'_y'});                          $env{'form.HWVAL_'.$id.'_'.$label.'S'.$ni.'_y'});
 # Run in small steps over spline parameter  # Run in small steps over spline parameter
             for (my $t=0; $t<=1; $t+=0.0001) {              for (my $t=0; $t<=1; $t+=0.0001) {
                 my $xi=&array_index($xmin,$xmax,&cubic_hermite($t,@xparms));                  my $xreal=&cubic_hermite($t,@xparms);
                   my $xi=&array_index($xmin,$xmax,$xreal);
                 if ($xi<$xiold) { return 'no_func'; }                  if ($xi<$xiold) { return 'no_func'; }
                 if (($xi>$xiold) && ($xi>=0) && ($xi<=400)) {                  if (($xi>$xiold) && ($xi>=0) && ($xi<=400)) {
                    if (defined($Apache::functionplotresponse::func[$xi])) { return 'no_func'; }  
                    $xiold=$xi;                     $xiold=$xi;
                      $Apache::functionplotresponse::actualxval[$xi]=$xreal;
 # Function value  # Function value
                    my $funcval=&cubic_hermite($t,@yparms);                     my $funcval=&cubic_hermite($t,@yparms);
   
   # Do we already have a value for this point, and is it different from the new one?
                      if ((defined($Apache::functionplotresponse::func[$xi])) &&
                          (abs($Apache::functionplotresponse::func[$xi]-$funcval)>($ymax-$ymin)/100.)) { 
                          return 'no_func'; 
                      }
   # Okay, remember the new point
                    $Apache::functionplotresponse::func[$xi]=$funcval;                     $Apache::functionplotresponse::func[$xi]=$funcval;
   
                    if (defined($funcval)) {                     if (defined($funcval)) {
                       if ($xi<$Apache::functionplotresponse::functionplotrulelabels{'start'}) {                        if ($xi<$Apache::functionplotresponse::functionplotrulelabels{'start'}) {
                          $Apache::functionplotresponse::functionplotrulelabels{'start'}=$xi;                           $Apache::functionplotresponse::functionplotrulelabels{'start'}=$xi;
Line 638  sub populate_arrays { Line 1067  sub populate_arrays {
                    my $dxdt=&ddt_cubic_hermite($t,@xparms);                     my $dxdt=&ddt_cubic_hermite($t,@xparms);
                    if ($dxdt) {                     if ($dxdt) {
                       $Apache::functionplotresponse::dfuncdx[$xi]=&ddt_cubic_hermite($t,@yparms)/$dxdt;                        $Apache::functionplotresponse::dfuncdx[$xi]=&ddt_cubic_hermite($t,@yparms)/$dxdt;
                    }  # Second derivative
 # Faa di Bruno  
 # d^2y/dx^2=(d^2y/dt^2)/(dx/dt)^2+(dy/dt)/(d^2x/dt^2)  
                    my $d2xdt2=&d2dt2_cubic_hermite($t,@xparms);  
                    if (($dxdt) && ($d2xdt2)) {  
                       $Apache::functionplotresponse::d2funcdx2[$xi]=                        $Apache::functionplotresponse::d2funcdx2[$xi]=
                          &d2dt2_cubic_hermite($t,@yparms)/($dxdt*$dxdt)                           ($dxdt*&d2dt2_cubic_hermite($t,@yparms)-&ddt_cubic_hermite($t,@yparms)*&d2dt2_cubic_hermite($t,@xparms))/
                         +&ddt_cubic_hermite($t,@yparms)/$d2xdt2;                           ($dxdt*$dxdt*$dxdt);
                    }                     }
                 }                  }
             }              }
Line 654  sub populate_arrays { Line 1079  sub populate_arrays {
 }  }
   
 #  #
 # Implentation of <functionplotresponse>  # Implementation of <functionplotresponse>
 #  #
   
 sub start_functionplotresponse {  sub start_functionplotresponse {
Line 672  sub start_functionplotresponse { Line 1097  sub start_functionplotresponse {
   $Apache::functionplotresponse::counter=0;    $Apache::functionplotresponse::counter=0;
 # Remember rules  # Remember rules
   undef @Apache::functionplotresponse::functionplotrules;    undef @Apache::functionplotresponse::functionplotrules;
     undef @Apache::functionplotresponse::functionplotvectorrules;
   # Remember failed rules
     if ($target eq 'grade') {
        undef @Apache::functionplotresponse::failedrules;
     }
   # Delete previous awards
     undef $Apache::functionplotresponse::awarddetail;
 # Part and ID  # Part and ID
   my $partid=$Apache::inputtags::part;    my $partid=$Apache::inputtags::part;
   my $id=&Apache::response::start_response($parstack,$safeeval);    my $id=&Apache::response::start_response($parstack,$safeeval);
Line 681  sub start_functionplotresponse { Line 1113  sub start_functionplotresponse {
   &decode_previous_answer($Apache::lonhomework::history{"resource.$partid.$id.submission"});    &decode_previous_answer($Apache::lonhomework::history{"resource.$partid.$id.submission"});
   
 # Parameters of <functionplotresponse>  # Parameters of <functionplotresponse>
   my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval);    my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval);
   $xmin=(defined($xmin)?$xmin:-10);  
   my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval);  
   $xmax=(defined($xmax)?$xmax:10);  
   my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval);  
   $ymin=(defined($ymin)?$ymin:-10);  
   my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval);  
   $ymax=(defined($ymax)?$ymax:10);  
   if ($xmax<=$xmin) {  
      &Apache::lonxml::warning('Maximum x-value needs to be larger than minimum value.');  
      $xmax=$xmin+20;  
   }  
   if ($ymax<=$ymin) {  
      &Apache::lonxml::warning('Maximum y-value needs to be larger than minimum value.');  
      $ymax=$ymin+20;  
   }  
   my $xaxisvisible=(&Apache::lonxml::get_param('xaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');    my $xaxisvisible=(&Apache::lonxml::get_param('xaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');
   my $yaxisvisible=(&Apache::lonxml::get_param('yaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');    my $yaxisvisible=(&Apache::lonxml::get_param('yaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');
   my $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');    my $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false');
Line 706  sub start_functionplotresponse { Line 1123  sub start_functionplotresponse {
     $result.=&Apache::edit::start_table($token)      $result.=&Apache::edit::start_table($token)
        .'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>'         .'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>'
        .'<td><span class="LC_nobreak">'.&mt('Delete?').' '         .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
        .&Apache::edit::deletelist($target,$token)         .&Apache::edit::deletelist($target,$token).'&nbsp;&nbsp;&nbsp;'
          .&Apache::edit::insertlist($target,$token).'&nbsp;&nbsp;&nbsp;'
          .&Apache::loncommon::help_open_topic('Function_Plot_Response_Question','Function Plot Responses')
        .'</span></td>'         .'</span></td>'
        ."<td>&nbsp;"         ."<td>&nbsp;"
        .&Apache::edit::end_row()         .&Apache::edit::end_row()
Line 719  sub start_functionplotresponse { Line 1138  sub start_functionplotresponse {
              &Apache::edit::text_arg('Maximum x-value:','xmax',               &Apache::edit::text_arg('Maximum x-value:','xmax',
                                      $token,'4').'&nbsp;'.                                       $token,'4').'&nbsp;'.
              &Apache::edit::select_arg('x-axis visible:','xaxisvisible',               &Apache::edit::select_arg('x-axis visible:','xaxisvisible',
                                   ['yes','no'],$token).'&nbsp;&nbsp;'.                                    ['yes','no'],$token).'<br />'.
              &Apache::edit::text_arg('Label y-axis:','ylabel',               &Apache::edit::text_arg('Label y-axis:','ylabel',
                                      $token,'6').'&nbsp;'.                                       $token,'6').'&nbsp;'.
              &Apache::edit::text_arg('Minimum y-value:','ymin',               &Apache::edit::text_arg('Minimum y-value:','ymin',
Line 727  sub start_functionplotresponse { Line 1146  sub start_functionplotresponse {
              &Apache::edit::text_arg('Maximum y-value:','ymax',               &Apache::edit::text_arg('Maximum y-value:','ymax',
                                      $token,'4').'&nbsp;'.                                       $token,'4').'&nbsp;'.
              &Apache::edit::select_arg('y-axis visible:','yaxisvisible',               &Apache::edit::select_arg('y-axis visible:','yaxisvisible',
                                   ['yes','no'],$token).'&nbsp;&nbsp;'.                                    ['yes','no'],$token).'<br />'.
              &Apache::edit::select_arg('Grid visible:','gridvisible',               &Apache::edit::select_arg('Grid visible:','gridvisible',
                                   ['yes','no'],$token).                                    ['yes','no'],$token).'<br />'.
                &Apache::edit::text_arg('Background plot(s) for answer (function(x):xmin:xmax,function(x):xmin:xmax,x1:y1:sx1:sy1:x2:y2:sx2:sy2,...):',
                                            'answerdisplay',$token,'50').
              &Apache::edit::end_row().&Apache::edit::start_spanning_row();               &Apache::edit::end_row().&Apache::edit::start_spanning_row();
   } elsif ($target eq 'modified') {    } elsif ($target eq 'modified') {
     my $constructtag=&Apache::edit::get_new_args($token,$parstack,      my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                                                  $safeeval,'xlabel','xmin','xmax','ylabel','ymin','ymax',                                                   $safeeval,'xlabel','xmin','xmax','ylabel','ymin','ymax',
                                                            'xaxisvisible','yaxisvisible','gridvisible');                                                             'xaxisvisible','yaxisvisible','gridvisible','answerdisplay');
     if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }      if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
   
   } elsif ($target eq 'meta') {    } elsif ($target eq 'meta') {
        $result=&Apache::response::meta_package_write('functionplotresponse');         $result=&Apache::response::meta_package_write('functionplotresponse');
   } elsif ($target eq 'web') {    } elsif (($target eq 'answer') &&
 # paste in the update routine to receive stuff back from the applet              ($env{'form.answer_output_mode'} ne 'tex') &&
      $result.=&update_script($internalid);              ($Apache::lonhomework::viewgrades == 'F')) {
 # start the initscript for this applet        my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser();
      $result.=&start_init_script($internalid);        my $windowopen=&Apache::lonhtmlcommon::javascript_docopen();
 # put the axis commands inside        my $start_page = &Apache::loncommon::start_page('Rules Log', undef,
      $result.=&axes_script($internalid,$xmin,$xmax,$ymin,$ymax,$xaxisvisible,$yaxisvisible,$gridvisible);                                                 {'only_body' => 1,
      $result.=&axes_label($internalid,$xlabel,$ylabel);                                                  'bgcolor'   => '#FFFFFF',
 # init script is left open                                                  'js_ready'  => 1,});
   }        my $end_page = &Apache::loncommon::end_page({'js_ready' => 1,});
         $uname =~s/\W//g;
         $udom  =~s/\W//g;
         my $function_name =
                   join('_','LONCAPA_scriptvars',$uname,$udom,
                        $env{'form.counter'},$Apache::lonxml::curdepth);
         my $rules_var ="<script type=\"text/javascript\">
   // <![CDATA[
       function $function_name() {newWindow=open('','new_W','width=500,height=500,scrollbars=1,resizable=yes');newWindow.$windowopen;newWindow.document.writeln('$start_page<pre>".
       $Apache::functionplotresponse::ruleslog.
       "<\\/pre>$end_page');newWindow.document.close();newWindow.focus()}
   // ]]>
   </script><a href=\"javascript:$function_name();void(0);\">".&mt('Rules Log')."</a><br />";
               &Apache::lonxml::add_script_result($rules_var);
           }
   
   return $result;    return $result;
 }  }
   
 sub compare_rel {  sub compare_rel {
    my ($relationship,$value,$realval,$tol)=@_;     my ($relationship,$value,$realval,$tol)=@_;
 # is the real value defined?  # is the real value undefined?
    unless (defined($realval)) {     unless (defined($realval)) {
   # the real value is not defined
       if ($relationship eq 'eq') {        if ($relationship eq 'eq') {
          if ($value eq 'undef') {           if ($value eq 'undef') {
             return 1;              return 1;
Line 773  sub compare_rel { Line 1210  sub compare_rel {
       }        }
    }     }
   
 # it is defined.  # is the expected value undefined?
      if ($value eq 'undef') {
   # but by now we know that the real value is defined
         return 0;
      }
   
   # both are defined.
    if ($relationship eq 'gt') {     if ($relationship eq 'gt') {
       return ($realval>$value);        return ($realval>$value);
    } elsif ($relationship eq 'ge') {     } elsif ($relationship eq 'ge') {
Line 790  sub compare_rel { Line 1233  sub compare_rel {
    return 0;     return 0;
 }  }
   
   sub addlog {
      my ($text)=@_;
      $text=~s/\'/\\\'/g;
      $Apache::functionplotresponse::ruleslog.=$text.'<br />';
   }
   
   sub actualval {
      my ($i,$xmin,$xmax)=@_;
      return $xmin+$i/400.*($xmax-$xmin);
   }
   
   sub fpr_val {
      my ($arg)=@_;
      return &actualval($Apache::functionplotresponse::functionplotrulelabels{$arg},
                        $Apache::functionplotresponse::fpr_xmin,
                        $Apache::functionplotresponse::fpr_xmax);
   }
   
   sub fpr_f {
      my ($arg)=@_;
      return $Apache::functionplotresponse::func[&array_index($Apache::functionplotresponse::fpr_xmin,
                                                              $Apache::functionplotresponse::fpr_xmax,
                                                              $arg)];
   }
   
   sub fpr_dfdx {
      my ($arg)=@_;
      return $Apache::functionplotresponse::dfuncdx[&array_index($Apache::functionplotresponse::fpr_xmin,
                                                                 $Apache::functionplotresponse::fpr_xmax,
                                                                 $arg)];
   }
   
   sub fpr_d2fdx2 {
      my ($arg)=@_;
      return $Apache::functionplotresponse::d2funcdx2[&array_index($Apache::functionplotresponse::fpr_xmin,
                                                                   $Apache::functionplotresponse::fpr_xmax,
                                                                   $arg)];
   }
    
 sub functionplotrulecheck {  sub functionplotrulecheck {
    my ($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)=@_;     my ($rule,$xmin,$xmax,$ymin,$ymax,$safeeval)=@_;
    &Apache::lonnet::logthis("Rule $rule TolFunc $tolfunc TolDfDx $toldfdx TolD2fDx2 $told2fdx2");  
    my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$relationship,$value)     my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$minimumlength,$maximumlength,$relationship,$value,$percent)
       =split(/\:/,$rule);        =split(/\:/,$rule);
      $percent=($percent>0?$percent:5);
      &addlog("=================");
      &addlog("Rule $label for ".($derivative<0?'integral':('function itself','first derivative','second derivative')[$derivative])." $relationship $value");
   #
   # Evaluate the value
   #
      if ($value=~/\D/) {
         $Apache::functionplotresponse::fpr_xmin=$xmin;
         $Apache::functionplotresponse::fpr_xmax=$xmax;
         $value=&Apache::run::run($value,$safeeval);
         &addlog("Value evaluated to $value");
      }
   
   #
   # Minimum and maximum lengths of the interval
   #
      if ((defined($minimumlength)) || (defined($maximumlength))) {
         &addlog("Minimumlength $minimumlength Maximumlength $maximumlength");
      }
    my $li=0;     my $li=0;
    my $lh=400;     my $lh=400;
   
Line 821  sub functionplotrulecheck { Line 1321  sub functionplotrulecheck {
    }     }
 # if the label is defined, use it  # if the label is defined, use it
    if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) {     if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) {
         &addlog("Using lower label $xinitiallabel");
       $li=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel};        $li=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel};
    } else {     } else {
       $li=&array_index($xmin,$xmax,$xinitial);        $li=&array_index($xmin,$xmax,$xinitial);
    }     }
    unless ($findupper) {     unless ($findupper) {
       if (defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel})) {        if (defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel})) {
          $lh=$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel};           &addlog("Using upper label $xfinallabel");
            $lh=$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}-1;
       } else {        } else {
          $lh=&array_index($xmin,$xmax,$xfinal);           $lh=&array_index($xmin,$xmax,$xfinal);
       }        }
Line 835  sub functionplotrulecheck { Line 1337  sub functionplotrulecheck {
 # Basic sanity checks  # Basic sanity checks
    if ($li<0) { $li=0; }     if ($li<0) { $li=0; }
    if ($lh>400) { $lh=400; }     if ($lh>400) { $lh=400; }
    if ($li>$lh) {     if (($li>$lh) || (!defined($lh))) {
        $lh=$li;         $lh=$li;
    }     }
   
    &Apache::lonnet::logthis("Init $xinitial=$li Final $xfinal=$lh Findupper: $findupper");     &addlog("Boundaries: x=".&actualval($li,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$li]."; index $li)) to x=".
    my $tol=$tolfunc;                              &actualval($lh,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$lh]."; index $lh))");
    if ($derivative==2) {     if ($findupper) {
       $tol=$told2fdx2;        &addlog("Looking for label $xfinallabel");
    } elsif ($derivative==1) {     }
       $tol=$toldfdx;     my $tol=$percent*($ymax-$ymin)/100;
      if ($xmax>$xmin) {
         if ($derivative==2) {
            $tol=4.*$tol/($xmax-$xmin);
         } elsif ($derivative==1) {
            $tol=2.*$tol/($xmax-$xmin);
         } elsif ($derivative==-1) {
            $tol=$tol*($xmax-$xmin)/2.;
         }
    }     }
    for (my $i=$li; $i<=$lh; $i++) {     my $integral=0;
      my $binwidth=($xmax-$xmin)/400.;
      if (($derivative<0) && (!$findupper)) {
   # definite integral, calculate over whole length
        &addlog("Calculating definite integral");
        for (my $i=$li; $i<=$lh; $i++) {
           $integral+=$Apache::functionplotresponse::func[$i]*$binwidth;
        }
        unless (&compare_rel($relationship,$value,$integral,$tol)) {
           &addlog("Actual integral ".(defined($integral)?$integral:'undef').", expected $value, tolerance $tol");
           &addlog("Rule $label failed.");
           my $hintlabel=$label;
           $hintlabel=~s/^R//;
           push(@Apache::functionplotresponse::failedrules,$hintlabel);
           &addlog("Set hint condition $hintlabel");
           return 0;
        } 
      } else {
        for (my $i=$li; $i<=$lh; $i++) {
         my $val;          my $val;
         if ($derivative==2) {          if ($derivative==2) {
            $val=$Apache::functionplotresponse::d2funcdx2[$i];             $val=$Apache::functionplotresponse::d2funcdx2[$i];
         } elsif ($derivative==1) {          } elsif ($derivative==1) {
            $val=$Apache::functionplotresponse::dfuncdx[$i];             $val=$Apache::functionplotresponse::dfuncdx[$i];
           } elsif ($derivative==-1) {
              $integral+=$Apache::functionplotresponse::func[$i]*$binwidth;
              $val=$integral;      
         } else {          } else {
            $val=$Apache::functionplotresponse::func[$i];             $val=$Apache::functionplotresponse::func[$i];
         }          }
         unless (&compare_rel($relationship,$value,$val,$tol)) {           unless (&compare_rel($relationship,$value,$val,$tol)) { 
            &Apache::lonnet::logthis("Condition false $findupper at $i with $val");             &addlog("Actual value ".(defined($val)?$val:'undef').", expected $value, tolerance $tol");
              &addlog("Condition not fulfilled at x=".&actualval($i,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$i]."; index $i)");
            if (($findupper) && ($i>$li)) {             if (($findupper) && ($i>$li)) {
   # Check lengths
                 unless (&checklength($i,$li,$minimumlength,$maximumlength,$xmin,$xmax,$label)) { return 0; }
   # Successfully found a new label, set it
               $Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$i;                $Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$i;
               &Apache::lonnet::logthis("Setting $xfinallabel to $i");                &addlog("Rule $label passed, setting label $xfinallabel");
               return 1;                return 1;
            } else {             } else {
                 &addlog("Rule $label failed.");
                 &setfailed($label);
               return 0;                 return 0; 
            }             }
         }          }
        }
    }     }
   # Corner case where this makes sense: using start or stop as defined labels
      unless (&checklength($lh,$li,$minimumlength,$maximumlength,$xmin,$xmax,$label)) { return 0; }
      &addlog("Rule $label passed.");
    return 1;     return 1;
 }  }
   
 sub end_functionplotresponse {  #
   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;  # check for minimum and maximum lengths
   &Apache::response::end_response;  #
   
   my $result;  sub checklength {
   my $id=$Apache::inputtags::response[-1];      my ($i,$li,$minimumlength,$maximumlength,$xmin,$xmax,$label)=@_;
   my $partid=$Apache::inputtags::part;      unless (($minimumlength) || ($maximumlength)) { return 1; }
   my $internalid = $partid.'_'.$id;      my $length=&actualval($i,$xmin,$xmax)-&actualval($li,$xmin,$xmax);
       if ($minimumlength) {
          if ($length<$minimumlength) {
             &addlog("Rule $label failed, actual length $length, minimum length $minimumlength");
             &setfailed($label);
             return 0;
          }
       }
       if ($maximumlength) {
          if ($length>$maximumlength) {
             &addlog("Rule $label failed, actual length $length, maximum length $maximumlength");
             &setfailed($label);
             return 0;
          }
       }
       return 1;
   }
   
     if ($target eq 'edit') { $result=&Apache::edit::end_table(); }  sub setfailed {
     if ($target eq 'grade'     my ($label)=@_;
          && &Apache::response::submitted()     my $hintlabel=$label;
          && $Apache::lonhomework::type eq 'exam') {     $hintlabel=~s/^R//;
      push(@Apache::functionplotresponse::failedrules,$hintlabel);
      &addlog("Set hint condition $hintlabel");
   }
   
         &Apache::response::scored_response($partid,$id);  sub start_functionplotruleset {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      if ($target eq 'edit') {
         return &Apache::edit::start_table($token).
           '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Rule Set').'</span></td>'
          .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
          .&Apache::edit::deletelist($target,$token).'&nbsp;&nbsp;&nbsp;'.
           &Apache::edit::insertlist($target,$token).'&nbsp;&nbsp;&nbsp;'
          .&Apache::loncommon::help_open_topic('Function_Plot_Response_Rule_Set','Function Plot Rules')
          .'</span></td>'
          ."<td>&nbsp;"
          .&Apache::edit::end_row()
          .&Apache::edit::start_spanning_row()
          ."\n";
      }
   }
   
     } elsif ($target eq 'grade'  sub end_functionplotruleset {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $id=$Apache::inputtags::response[-1];
       my $partid=$Apache::inputtags::part;
       my $internalid = $partid.'_'.$id;
   
       if ($target eq 'edit' ) {
           return &Apache::edit::end_table();
       }  elsif ($target eq 'grade'
          && &Apache::response::submitted()           && &Apache::response::submitted()
          && $Apache::lonhomework::type ne 'exam') {           && $Apache::lonhomework::type ne 'exam') {
         my ($response,%coords)=&get_answer_from_form_fields($internalid);  
         $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;  
         my %previous=&Apache::response::check_for_previous($response,$partid,$id);  
 #  #
 # Actually grade  # Actually grade
 #  #
         my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval);      my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-2);
         $xmin=(defined($xmin)?$xmin:-10);  
         my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval);  
         $xmax=(defined($xmax)?$xmax:10);  
         my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval);  
         $ymin=(defined($ymin)?$ymin:-10);  
         my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval);  
         $ymax=(defined($ymax)?$ymax:10);  
   
         my $percent=&Apache::lonxml::get_param('percenterror',$parstack,$safeeval);  
         $percent=(defined($percent)?$percent:5);  
   
         my $tolfunc=$percent*($ymax-$ymin)/100.;  
         my $toldfdx=1;  
         my $told2fdx2=1;  
         if ($xmax>$xmin) {  
            $toldfdx=$tolfunc/($xmax-$xmin);  
            $told2fdx2=$toldfdx/($xmax-$xmin);  
         }  
   
         my $ad='';          my $ad='';
         undef  %Apache::functionplotresponse::functionplotrulelabels;          undef  %Apache::functionplotresponse::functionplotrulelabels;
           $Apache::functionplotresponse::ruleslog='';
         $Apache::functionplotresponse::functionplotrulelabels{'start'}=400;          $Apache::functionplotresponse::functionplotrulelabels{'start'}=400;
         $Apache::functionplotresponse::functionplotrulelabels{'end'}=0;          $Apache::functionplotresponse::functionplotrulelabels{'end'}=0;
         if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') {          if (&populate_arrays($internalid,$xmin,$xmax,$ymin,$ymax) eq 'no_func') {
            $ad='NOT_FUNCTION';             $ad='NOT_FUNCTION';
         } else {          } else {
              &addlog("Start of function ".&actualval($Apache::functionplotresponse::functionplotrulelabels{'start'},$xmin,$xmax)." (index ".
                                           $Apache::functionplotresponse::functionplotrulelabels{'start'}.")");
              &addlog("End of function ".&actualval($Apache::functionplotresponse::functionplotrulelabels{'end'},$xmin,$xmax)." (index ".
                                           $Apache::functionplotresponse::functionplotrulelabels{'end'}.")");
   
 # We have a function that we can actually grade, go through the spline rules.  # We have a function that we can actually grade, go through the spline rules.
            foreach my $rule (@Apache::functionplotresponse::functionplotrules) {             foreach my $rule (@Apache::functionplotresponse::functionplotrules) {
               unless (&functionplotrulecheck($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)) {                unless (&functionplotrulecheck($rule,$xmin,$xmax,$ymin,$ymax,$safeeval)) {
                  $ad='INCORRECT';                   $ad='INCORRECT';
                  last;                   last;
               }                }
Line 931  sub end_functionplotresponse { Line 1499  sub end_functionplotresponse {
 # If it's not wrong, it's correct   # If it's not wrong, it's correct 
            unless ($ad) { $ad='EXACT_ANS' };             unless ($ad) { $ad='EXACT_ANS' };
         }          }
           &addlog("Set hint conditions: ".join(",",@Apache::functionplotresponse::failedrules));
           &addlog("Assigned award detail: $ad");
   # Store for later to be assigned at end_functionplotresponse
           $Apache::functionplotresponse::awarddetail=$ad;
        }
   }
   
   
   sub end_functionplotresponse {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     &Apache::response::end_response;
   
     my $result;
     my $id=$Apache::inputtags::response[-1];
     my $partid=$Apache::inputtags::part;
     my $internalid = $partid.'_'.$id;
   
       if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
       if ($target eq 'grade'
            && &Apache::response::submitted()
            && $Apache::lonhomework::type eq 'exam') {
   
           &Apache::response::scored_response($partid,$id);
   
       } elsif ($target eq 'grade'
            && &Apache::response::submitted()
            && $Apache::lonhomework::type ne 'exam') {
           my ($response,%coords)=&get_answer_from_form_fields($internalid);
           $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
           my %previous=&Apache::response::check_for_previous($response,$partid,$id);
   #
   # Assign grade
   #
           my $ad=$Apache::functionplotresponse::awarddetail;
 #  #
 # Store grading info  # Store grading info
 #  #
         $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;          $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;
         &Apache::response::handle_previous(\%previous,$ad);          &Apache::response::handle_previous(\%previous,$ad);
    } elsif ($target eq 'web') {     } elsif ($target eq 'web') {
           undef @Apache::functionplotresponse::failedrules;
      }
      return $result;
   }
   
   sub end_functionplotelements {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $result='';
     my $id=$Apache::inputtags::response[-1];
     my $partid=$Apache::inputtags::part;
     my $internalid = $partid.'_'.$id;
     if ($target eq 'edit' ) {
        $result=&Apache::edit::end_table();
     } elsif ($target eq 'web') {
        my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-2);
   
   # Are we in show answer mode?
        my $showanswer=&Apache::response::show_answer();
        if ($showanswer) {
   # Render answerdisplay
           my $answerdisplay=&Apache::lonxml::get_param('answerdisplay',$parstack,$safeeval,-2);
           if ($answerdisplay=~/\S/s) {
              foreach my $plot (split(/\s*\,\s*/,$answerdisplay)) {
                 my @components=split(/\s*\:\s*/,$plot);
                 if ($#components<3) {
   # Just a simple plot
                    my ($func,$xl,$xh)=@components;
                    if ((!defined($xl)) || ($xl eq '')) { $xl=$xmin; }
                    if ((!defined($xh)) || ($xh eq '')) { $xh=$xmax; }
                    $result.=&plot_script($internalid,$func,1,'','00aa00',$xl,$xh,6);
                 } else {
   # This is a spline
                    $result.=&answer_spline_script($internalid,@components);
                 }
              }
           }
        }
        my $fixed=0;
        if (($showanswer) || (&Apache::response::check_status()>=2)) { $fixed=1; }
 # Now is the time to render all of the stored splines  # Now is the time to render all of the stored splines
      foreach my $label (keys(%Apache::functionplotresponse::splineorder)) {       foreach my $label (keys(%Apache::functionplotresponse::splineorder)) {
         $result.=&generate_spline($internalid,$label);          $result.=&generate_spline($internalid,$label,$xmin,$xmax,$ymin,$ymax,$fixed);
      }       }
 # close the init script  # close the init script
      $result.=&end_init_script();       $result.=&end_init_script();
Line 964  sub end_functionplotresponse { Line 1604  sub end_functionplotresponse {
   }    }
   return $result;    return $result;
 }  }
   
   sub boundaries {
      my ($parstack,$safeeval,$level)=@_;
      my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval,$level);
      $xmin=(defined($xmin)?$xmin:-10);
      my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval,$level);
      $xmax=(defined($xmax)?$xmax:10);
      my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval,$level);
      $ymin=(defined($ymin)?$ymin:-10);
      my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval,$level);
      $ymax=(defined($ymax)?$ymax:10);
      if ($xmax<=$xmin) {
         $xmax=$xmin+20;
      }
      if ($ymax<=$ymin) {
         $ymax=$ymin+20;
      }
      return ($xmin,$xmax,$ymin,$ymax);
   }
   
   sub start_functionplotelements {
      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
      my $result='';
      my $id=$Apache::inputtags::response[-1];
      my $partid=$Apache::inputtags::part;
      my $internalid = $partid.'_'.$id;
   
      if ($target eq 'edit') {
         return &Apache::edit::start_table($token).
           '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Elements').'</span></td>'
          .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
          .&Apache::edit::deletelist($target,$token).'&nbsp;&nbsp;&nbsp;'.
           &Apache::edit::insertlist($target,$token).'&nbsp;&nbsp;&nbsp;'
          .&Apache::loncommon::help_open_topic('Function_Plot_Response_Elements','Function Plot Elements')
          .'</span></td>'
          ."<td>&nbsp;"
          .&Apache::edit::end_row()
          .&Apache::edit::start_spanning_row()
          ."\n";
      } elsif ($target eq 'web') {
         my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-2);
         my $xaxisvisible=(&Apache::lonxml::get_param('xaxisvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
         my $yaxisvisible=(&Apache::lonxml::get_param('yaxisvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
         my $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
         my $xlabel=&Apache::lonxml::get_param('xlabel',$parstack,$safeeval,-2);
         my $ylabel=&Apache::lonxml::get_param('ylabel',$parstack,$safeeval,-2);
   
   
   # paste in the update routine to receive stuff back from the applet
        $result.=&update_script($internalid);
   # start the initscript for this applet
        $result.=&start_init_script($internalid);
   # put the axis commands inside
        $result.=&axes_script($internalid,$xmin,$xmax,$ymin,$ymax,$xaxisvisible,$yaxisvisible,$gridvisible);
        $result.=&axes_label($internalid,$xmin,$xmax,$ymin,$ymax,$xlabel,$ylabel);
   # init script is left open
     }
     return $result;
   }
   
 1;  1;
   

Removed from v.1.31  
changed lines
  Added in v.1.75


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.