--- loncom/homework/functionplotresponse.pm 2010/10/09 22:31:49 1.12 +++ loncom/homework/functionplotresponse.pm 2010/10/28 00:27:56 1.16 @@ -1,7 +1,7 @@ # LearningOnline Network with CAPA # option list style responses # -# $Id: functionplotresponse.pm,v 1.12 2010/10/09 22:31:49 www Exp $ +# $Id: functionplotresponse.pm,v 1.16 2010/10/28 00:27:56 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -101,12 +101,25 @@ ENDDEFAULTPARAMETERS # sub init_script { - if ($Apache::functionplotresponse::callscripts) { + if ($#Apache::functionplotresponse::callscripts>=0) { + my $script=''; + foreach my $id (@Apache::functionplotresponse::callscripts) { + $script.="if (param=='applet_$id') { loaded_$id=true; }\n"; + } + $script.="if (".join(' && ',map { "loaded_$_" } (@Apache::functionplotresponse::callscripts)). + ") { setTimeout('ggbInitAll()',20) }\n"; + my $calls=join("\n",map { "ggbInit_$_();" } (@Apache::functionplotresponse::callscripts)); return (< // @@ -194,14 +207,16 @@ sub new_coordinate { # sub start_init_script { my ($id)=@_; -# Add a line to ggbOnInit-function which calls the right function based on parameter passed from GeoGebra - $Apache::functionplotresponse::callscripts.="if (param=='applet_$id') { ggbInit_$id(); }\n"; +# Add id to the list of ggbInit_$id functions that need to be called + push(@Apache::functionplotresponse::callscripts,$id); # ... and open this function return (< // 8) { $order=8; } - $Apache::functionplotresponse::splineorder{$label}=$order; - - my $x=&Apache::lonxml::get_param('initx',$parstack,$safeeval); - unless ($x) { $x=0; } - $Apache::functionplotresponse::splineinitx{$label}=$x; - - my $y=&Apache::lonxml::get_param('inity',$parstack,$safeeval); - unless ($y) { $y=0; } - $Apache::functionplotresponse::splineinity{$label}=$y; - - my $sx=&Apache::lonxml::get_param('scalex',$parstack,$safeeval); - unless ($sx) { $sx=$order; } - $Apache::functionplotresponse::splinescalex{$label}=$sx; - - my $sy=&Apache::lonxml::get_param('scaley',$parstack,$safeeval); - unless ($sy) { $sy=2; } - $Apache::functionplotresponse::splinescaley{$label}=$sy; - return ''; + my $result=''; + if ($target eq 'web') { + my $label=&Apache::lonxml::get_param('label',$parstack,$safeeval); + $Apache::functionplotresponse::counter++; + if ($label=~/\W/) { + &Apache::lonxml::warning(&mt('Spline labels should only contain alphanumeric characters.')); + } + $label=~s/\W//gs; + unless ($label) { $label='S'.$Apache::functionplotresponse::counter; } + if ($Apache::functionplotresponse::splineorder{$label}) { + &Apache::lonxml::error(&mt('Spline labels must be unique.')); + } + + my $order=&Apache::lonxml::get_param('order',$parstack,$safeeval); + if ($order<2) { $order=2; } + if ($order>8) { $order=8; } + $Apache::functionplotresponse::splineorder{$label}=$order; + + my $x=&Apache::lonxml::get_param('initx',$parstack,$safeeval); + unless ($x) { $x=0; } + $Apache::functionplotresponse::splineinitx{$label}=$x; + + my $y=&Apache::lonxml::get_param('inity',$parstack,$safeeval); + unless ($y) { $y=0; } + $Apache::functionplotresponse::splineinity{$label}=$y; + + my $sx=&Apache::lonxml::get_param('scalex',$parstack,$safeeval); + unless ($sx) { $sx=$order; } + $Apache::functionplotresponse::splinescalex{$label}=$sx; + + my $sy=&Apache::lonxml::get_param('scaley',$parstack,$safeeval); + unless ($sy) { $sy=2; } + $Apache::functionplotresponse::splinescaley{$label}=$sy; + } elsif ($target eq 'edit') { + $result=&Apache::edit::tag_start($target,$token,'Spline'). + &Apache::edit::text_arg('Label:','label', + $token,'4').' '. + &Apache::edit::select_arg('Order:','order', + ['2','3','4','5','6','7','8','9'],$token).' '. + &Apache::edit::text_arg('Initial x-value:','initx', + $token,'4').' '. + &Apache::edit::text_arg('Initial y-value:','inity', + $token,'4').' '. + &Apache::edit::text_arg('Scale x:','scalex', + $token,'4').' '. + &Apache::edit::text_arg('Scale y:','scaley', + $token,'4'). + &Apache::edit::end_row(); + } elsif ($target eq 'modified') { + my $constructtag=&Apache::edit::get_new_args($token,$parstack, + $safeeval,'label','order','initx','inity', + 'scalex','scaley'); + if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); } + } + return $result; } sub end_spline { - return ''; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $result=''; + if ($target eq 'edit') { + $result=&Apache::edit::end_table(); + } + return $result; } sub end_init_script { @@ -371,6 +468,40 @@ sub get_answer_from_form_fields { return ($answer,%coords); } +# +# The following functions calculate the cubic-hermite splines server-side +# + +sub cubic_hermite { + 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)+ + (-2.*$t*$t*$t+3.*$t*$t) *$p2 + 5.*($t*$t*$t-$t*$t) *($s2-$p2); +} + +# +# d/dt(...) +# + +sub ddt_cubic_hermite { + my ($t,$p1,$s1,$p2,$s2)=@_; + return (6.*$t*$t-6.*$t) *$p1 + 5.*(3.*$t*$t-4.*$t+1.)*($s1-$p1)+ + (-6.*$t*$t+6.*$t)*$p2 + 5.*(3.*$t*$t-2.*$t) *($s2-$p2); +} + +# +# d^2/dt^2(...) +# + +sub d2dt2_cubic_hermite { + my ($t,$p1,$s1,$p2,$s2)=@_; + return (12.*$t-6.) *$p1 + 5.*(6.*$t-4.)*($s1-$p1)+ + (-12.*$t+6.)*$p2 + 5.*(6.*$t-2.)*($s2-$p2); +} + +# +# Implentation of +# + sub start_functionplotresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; @@ -404,6 +535,8 @@ sub start_functionplotresponse { 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 $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false'); + my $xlabel=&Apache::lonxml::get_param('xlabel',$parstack,$safeeval); + my $ylabel=&Apache::lonxml::get_param('ylabel',$parstack,$safeeval); if ($target eq 'edit') { $result.=&Apache::edit::start_table($token) .''.&mt('Function Plot Question').'' @@ -414,24 +547,28 @@ sub start_functionplotresponse { .&Apache::edit::end_row() .&Apache::edit::start_spanning_row() ."\n"; - $result.=&Apache::edit::text_arg('Minimum x-value:','xmin', - $token,'4'). + $result.=&Apache::edit::text_arg('Label x-axis:','xlabel', + $token,'6').' '. + &Apache::edit::text_arg('Minimum x-value:','xmin', + $token,'4').' '. &Apache::edit::text_arg('Maximum x-value:','xmax', - $token,'4'). + $token,'4').' '. &Apache::edit::select_arg('x-axis visible:','xaxisvisible', - ['yes','no'],$token). + ['yes','no'],$token).'  '. + &Apache::edit::text_arg('Label y-axis:','ylabel', + $token,'6').' '. &Apache::edit::text_arg('Minimum y-value:','ymin', - $token,'4'). + $token,'4').' '. &Apache::edit::text_arg('Maximum y-value:','ymax', - $token,'4'). + $token,'4').' '. &Apache::edit::select_arg('y-axis visible:','yaxisvisible', - ['yes','no'],$token). + ['yes','no'],$token).'  '. &Apache::edit::select_arg('Grid visible:','gridvisible', ['yes','no'],$token). &Apache::edit::end_row().&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { my $constructtag=&Apache::edit::get_new_args($token,$parstack, - $safeeval,'xmin','xmax','ymin','ymax', + $safeeval,'xlabel','xmin','xmax','ylabel','ymin','ymax', 'xaxisvisible','yaxisvisible','gridvisible'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); } @@ -444,6 +581,7 @@ sub start_functionplotresponse { $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,$xlabel,$ylabel); # init script is left open } return $result;