Annotation of loncom/homework/imageresponse.pm, revision 1.57
1.12 albertel 1: # The LearningOnline Network with CAPA
1.14 albertel 2: # image click response style
3: #
1.57 ! albertel 4: # $Id: imageresponse.pm,v 1.56 2004/10/21 06:37:36 albertel Exp $
1.14 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.25 www 28: #FIXME LATER assumes multiple possible submissions but only one is possible
29: #currently
1.3 albertel 30:
1.1 albertel 31: package Apache::imageresponse;
32: use strict;
1.51 albertel 33: use Image::Magick();
34: use Apache::randomlylabel();
35: use Apache::londefdef();
1.40 albertel 36: use Apache::Constants qw(:common :http);
1.51 albertel 37: use Apache::lonlocal;
1.1 albertel 38:
1.16 harris41 39: BEGIN {
1.36 albertel 40: &Apache::lonxml::register('Apache::imageresponse',('imageresponse'));
1.1 albertel 41: }
42:
43: sub start_imageresponse {
1.36 albertel 44: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
45: my $result;
46: #when in a radiobutton response use these
1.43 albertel 47: &Apache::lonxml::register('Apache::imageresponse',
48: ('foilgroup','foil','text','image','rectangle',
49: 'polygon','conceptgroup'));
1.36 albertel 50: push (@Apache::lonxml::namespace,'imageresponse');
51: my $id = &Apache::response::start_response($parstack,$safeeval);
1.51 albertel 52: undef(%Apache::response::foilnames);
1.36 albertel 53: if ($target eq 'meta') {
54: $result=&Apache::response::meta_package_write('imageresponse');
1.37 albertel 55: } elsif ($target eq 'analyze') {
56: my $part_id="$Apache::inputtags::part.$id";
57: push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
1.36 albertel 58: }
59: return $result;
1.1 albertel 60: }
61:
62: sub end_imageresponse {
1.30 albertel 63: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
64: &Apache::response::end_response;
65: pop @Apache::lonxml::namespace;
66: &Apache::lonxml::deregister('Apache::imageresponse',('foilgroup','foil','text','image','rectangle','conceptgroup'));
67: my $result;
68: if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
1.51 albertel 69: undef(%Apache::response::foilnames);
1.30 albertel 70: return $result;
1.1 albertel 71: }
72:
1.20 albertel 73: %Apache::response::foilgroup=();
1.1 albertel 74: sub start_foilgroup {
1.36 albertel 75: %Apache::response::foilgroup=();
76: $Apache::imageresponse::conceptgroup=0;
1.53 albertel 77: &Apache::response::pushrandomnumber();
1.36 albertel 78: return '';
1.1 albertel 79: }
80:
1.2 albertel 81: sub getfoilcounts {
1.36 albertel 82: my ($parstack,$safeeval)=@_;
1.12 albertel 83:
1.36 albertel 84: my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2');
85: # +1 since instructors will count from 1
86: my $count = $#{ $Apache::response::foilgroup{'names'} }+1;
1.56 albertel 87: #if (&Apache::response::showallfoils()) { $max=$count; }
1.36 albertel 88: return ($count,$max);
1.2 albertel 89: }
90:
91: sub whichfoils {
1.36 albertel 92: my ($max)=@_;
93: if (!defined(@{ $Apache::response::foilgroup{'names'} })) { return; }
94: my @names = @{ $Apache::response::foilgroup{'names'} };
95: my @whichopt =();
96: while ((($#whichopt+1) < $max) && ($#names > -1)) {
97: &Apache::lonxml::debug("Have $#whichopt max is $max");
98: my $aopt;
1.56 albertel 99: # if (&Apache::response::showallfoils()) {
100: # $aopt=0;
101: # } else {
1.36 albertel 102: $aopt=int(&Math::Random::random_uniform() * ($#names+1));
1.56 albertel 103: # }
1.36 albertel 104: &Apache::lonxml::debug("From $#names elms, picking $aopt");
105: $aopt=splice(@names,$aopt,1);
106: &Apache::lonxml::debug("Picked $aopt");
107: push (@whichopt,$aopt);
108: }
109: return @whichopt;
1.2 albertel 110: }
111:
1.40 albertel 112: sub prep_image {
1.42 albertel 113: my ($image,$mode,$name)=@_;
1.40 albertel 114: my $part=$Apache::inputtags::part;
1.41 albertel 115: my $respid=$Apache::inputtags::response['-1'];
116: my $id=&Apache::loncommon::get_cgi_id();
1.49 albertel 117: my (%x,$i);
1.47 albertel 118: $x{"cgi.$id.BGIMG"}=&Apache::lonnet::escape($image);
1.41 albertel 119: my ($x,$y)=split(/:/,$Apache::lonhomework::history{"resource.$part.$respid.submission"});
1.40 albertel 120: #draws 2 xs on the image at the clicked location
121: #one in white and then one in red on top of the one in white
1.48 albertel 122: if (defined($x) && $x=~/\S/ && defined($y) && $y =~/\S/) {
1.40 albertel 123: my $length = 6;
124: my $width = 1;
125: my $extrawidth = 2;
1.48 albertel 126: my $xmin=($x-$length);
127: my $xmax=($x+$length);
128: my $ymin=($y-$length);
129: my $ymax=($y+$length);
130:
1.49 albertel 131: $x{"cgi.$id.OBJTYPE"}.='LINE:';
132: $i=$x{"cgi.$id.OBJCOUNT"}++;
1.57 ! albertel 133: $x{"cgi.$id.OBJ$i"}=join(':',(($x),($ymin),($x),($ymax),
1.49 albertel 134: "FFFFFF",($width+$extrawidth)));
135: $x{"cgi.$id.OBJTYPE"}.='LINE:';
136: $i=$x{"cgi.$id.OBJCOUNT"}++;
1.57 ! albertel 137: $x{"cgi.$id.OBJ$i"}=join(':',(($xmin),($y),($xmax),($y),
1.49 albertel 138: "FFFFFF",($width+$extrawidth)));
139: $x{"cgi.$id.OBJTYPE"}.='LINE:';
140: $i=$x{"cgi.$id.OBJCOUNT"}++;
1.57 ! albertel 141: $x{"cgi.$id.OBJ$i"}=join(':',(($x),($ymin),($x),($ymax),
1.49 albertel 142: "FF0000",($width)));
143: $x{"cgi.$id.OBJTYPE"}.='LINE:';
144: $i=$x{"cgi.$id.OBJCOUNT"}++;
1.57 ! albertel 145: $x{"cgi.$id.OBJ$i"}=join(':',(($xmin),($y),($xmax),($y),
1.49 albertel 146: "FF0000",($width)));
1.40 albertel 147: }
1.42 albertel 148: if ($mode eq 'answer') {
149: my $width = 1;
150: my $extrawidth = 2;
151: my @areas = @{ $Apache::response::foilgroup{"$name.area"} };
152: foreach my $area (@areas) {
1.43 albertel 153: if ($area=~/^rectangle:/) {
1.49 albertel 154: $x{"cgi.$id.OBJTYPE"}.='RECTANGLE:';
155: $i=$x{"cgi.$id.OBJCOUNT"}++;
1.43 albertel 156: my ($x1,$y1,$x2,$y2)=
157: ($area=~m/rectangle:\(([0-9]+),([0-9]+)\)\-\(([0-9]+),([0-9]+)\)/);
1.49 albertel 158: $x{"cgi.$id.OBJ$i"}=join(':',($x1,$y1,$x2,$y2,"FFFFFF",
1.43 albertel 159: ($width+$extrawidth)));
1.49 albertel 160: $x{"cgi.$id.OBJTYPE"}.='RECTANGLE:';
161: $i=$x{"cgi.$id.OBJCOUNT"}++;
162: $x{"cgi.$id.OBJ$i"}=join(':',($x1,$y1,$x2,$y2,"00FF00",$width));
1.43 albertel 163: } elsif ($area=~/^polygon:(.*)/) {
1.49 albertel 164: $x{"cgi.$id.OBJTYPE"}.='POLYGON:';
165: $i=$x{"cgi.$id.OBJCOUNT"}++;
166: $x{"cgi.$id.OBJ$i"}=join(':',("FFFFFF",($width+$extrawidth)));
167: $x{"cgi.$id.OBJEXTRA$i"}=$1;
168: $x{"cgi.$id.OBJTYPE"}.='POLYGON:';
169: $i=$x{"cgi.$id.OBJCOUNT"}++;
170: $x{"cgi.$id.OBJ$i"}=join(':',("00FF00",$width));
171: $x{"cgi.$id.OBJEXTRA$i"}=$1;
1.43 albertel 172: }
1.42 albertel 173: }
174: }
1.41 albertel 175: &Apache::lonnet::appenv(%x);
176: return $id;
1.40 albertel 177: }
178:
1.2 albertel 179: sub displayfoils {
1.36 albertel 180: my ($target,@whichopt) = @_;
181: my $result ='';
182: my $name;
183: my $temp=1;
184: foreach $name (@whichopt) {
185: $result.=$Apache::response::foilgroup{"$name.text"};
186: &Apache::lonxml::debug("Text is $result");
187: if ($target eq 'tex') {$result.="\\vskip 0 mm \n";} else {$result.="<br />\n";}
188: my $image=$Apache::response::foilgroup{"$name.image"};
189: &Apache::lonxml::debug("image is $image");
1.40 albertel 190: if ( $target eq 'web' && $image !~ /^http:/ ) {
1.47 albertel 191: $image=&clean_up_image($image);
192: }
1.40 albertel 193: &Apache::lonxml::debug("image is $image");
1.36 albertel 194: if ( &Apache::response::show_answer() ) {
195: if ($target eq 'tex') {
196: $result.=$Apache::response::foilgroup{"$name.image"}."\\vskip 0 mm \n";
197: } else {
1.42 albertel 198: my $token=&prep_image($image,'answer',$name);
1.40 albertel 199: $result.="<img src=\"/adm/randomlabel.png?token=$token\" /><br />\n";
1.36 albertel 200: }
201: } else {
202: if ($target eq 'tex') {
203: $result.=$Apache::response::foilgroup{"$name.image"}."\\vskip 0 mm \n";
204: } else {
1.40 albertel 205: my $id=$Apache::inputtags::response['-1'];
206: my $token=&prep_image($image);
207: my $temp=1;
208: $result.="<input type=\"image\" name=\"HWVAL_$id:$temp\" ".
209: "src=\"/adm/randomlabel.png?token=$token\" /><br />\n";
1.36 albertel 210: }
211: }
212: $temp++;
213: }
214: return $result;
1.47 albertel 215: }
216:
217: sub clean_up_image {
218: my ($image)=@_;
219: if ($image =~ /\s*<img\s*/) {
1.50 albertel 220: ($image) = ($image =~ /src\s*=\s*[\"\']([^\"\']+)[\"\']/i);
1.47 albertel 221: if ($image !~ /^http:/) {
222: $image=&Apache::lonnet::hreflocation('',$image);
223: }
224: if (!$image) {
225: $image='/home/httpd/html/adm/lonKaputt/lonlogo_broken.gif';
226: }
227: } else {
228: $image=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$image);
229: if (&Apache::lonnet::repcopy($image) ne OK) {
230: $image='/home/httpd/html/adm/lonKaputt/lonlogo_broken.gif';
231: }
232: }
233: return $image;
1.2 albertel 234: }
235:
1.3 albertel 236: sub gradefoils {
1.36 albertel 237: my (@whichopt) = @_;
238: my $x;
239: my $y;
240: my $result;
241: my $id=$Apache::inputtags::response['-1'];
242: my $temp=1;
243: foreach my $name (@whichopt) {
244: $x=$ENV{"form.HWVAL_$id:$temp.x"};
245: $y=$ENV{"form.HWVAL_$id:$temp.y"};
246: &Apache::lonxml::debug("Got a x of $x and a y of $y for $name");
247: if (defined($x) && defined($y) &&
248: defined(@{ $Apache::response::foilgroup{"$name.area"} })) {
249: my @areas = @{ $Apache::response::foilgroup{"$name.area"} };
250: my $grade="INCORRECT";
251: foreach my $area (@areas) {
252: &Apache::lonxml::debug("Area is $area for $name");
253: $area =~ m/([a-z]*):/;
254: &Apache::lonxml::debug("Area of type $1");
255: if ($1 eq 'rectangle') {
256: $grade=&grade_rectangle($area,$x,$y);
1.43 albertel 257: } elsif ($1 eq 'polygon') {
258: $grade=&grade_polygon($area,$x,$y);
1.36 albertel 259: } else {
260: &Apache::lonxml::error("Unknown area style $area");
261: }
262: &Apache::lonxml::debug("Area said $grade");
263: if ($grade eq 'APPROX_ANS') { last; }
264: }
265: &Apache::lonxml::debug("Foil was $grade");
266: if ($grade eq 'INCORRECT') { $result= 'INCORRECT'; }
267: if (($grade eq 'APPROX_ANS') && ($result ne 'APPROX_ANS')) { $result=$grade; }
268: &Apache::lonxml::debug("Question is $result");
269: $temp++;
1.9 albertel 270: }
1.36 albertel 271: }
1.56 albertel 272: if ($result
273: && $Apache::lonhomework::type eq 'survey') { $result='SUBMITTED'; }
1.36 albertel 274: $Apache::lonhomework::results{"resource.$Apache::inputtags::part.$id.submission"}="$x:$y";
275: $Apache::lonhomework::results{"resource.$Apache::inputtags::part.$id.awarddetail"}=$result;
276: return '';
1.3 albertel 277: }
278:
1.1 albertel 279: sub end_foilgroup {
1.36 albertel 280: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
281: my $result='';
282: my @whichopt;
1.38 albertel 283: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
284: $target eq 'analyze') {
1.36 albertel 285: my ($count,$max) = &getfoilcounts($parstack,$safeeval);
286: if ($count>$max) { $count=$max }
287: &Apache::lonxml::debug("Count is $count from $max");
288: @whichopt = &whichfoils($max);
289: if ($target eq 'web' || $target eq 'tex') {
290: $result=&displayfoils($target,@whichopt);
291: } elsif ($target eq 'grade') {
292: if ( defined $ENV{'form.submitted'}) { &gradefoils(@whichopt); }
1.37 albertel 293: } elsif ( $target eq 'analyze') {
294: &Apache::response::analyze_store_foilgroup(\@whichopt,
295: ['text','image','area']);
296: }
1.36 albertel 297: } elsif ($target eq 'edit') {
298: $result=&Apache::edit::end_table();
299: }
1.53 albertel 300: &Apache::response::poprandomnumber();
1.36 albertel 301: return $result;
1.1 albertel 302: }
303:
304: sub start_conceptgroup {
1.36 albertel 305: $Apache::imageresponse::conceptgroup=1;
306: %Apache::response::conceptgroup=();
307: return '';
1.1 albertel 308: }
309:
310: sub end_conceptgroup {
1.36 albertel 311: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
312: $Apache::imageresponse::conceptgroup=0;
313: my $result;
1.37 albertel 314: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
315: $target eq 'analyze') {
316: &Apache::response::pick_foil_for_concept($target,
317: ['area','text','image'],
318: \%Apache::hint::image,
319: $parstack,$safeeval);
1.36 albertel 320: } elsif ($target eq 'edit') {
321: $result=&Apache::edit::end_table();
322: }
323: return $result;
1.31 albertel 324: }
325:
326: sub insert_foil {
327: return '
328: <foil>
329: <image></image>
330: <text></text>
331: <rectangle></rectangle>
332: </foil>
333: ';
1.1 albertel 334: }
335:
1.12 albertel 336: $Apache::imageresponse::curname='';
1.1 albertel 337: sub start_foil {
1.36 albertel 338: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.37 albertel 339: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
340: $target eq 'analyze') {
1.36 albertel 341: my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
342: if ($name eq '') { $name=$Apache::lonxml::curdepth; }
1.51 albertel 343: if (defined($Apache::response::foilnames{$name})) {
344: &Apache::lonxml::error(&mt("Foil name <b><tt>[_1]</tt></b> appears more than once. Foil names need to be unique.",$name));
345: }
1.52 albertel 346: $Apache::response::foilnames{$name}++;
1.36 albertel 347: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 348: #&& !&Apache::response::showallfoils()
349: ) {
1.36 albertel 350: push(@{ $Apache::response::conceptgroup{'names'} }, $name);
351: } else {
352: push(@{ $Apache::response::foilgroup{'names'} }, $name);
353: }
354: $Apache::imageresponse::curname=$name;
355: }
356: return '';
1.1 albertel 357: }
358:
359: sub end_foil {
1.26 albertel 360: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
361: my $result;
362: if ($target eq 'edit') {
363: $result=&Apache::edit::end_table();
364: }
365: return $result;
1.1 albertel 366: }
367:
368: sub start_text {
1.36 albertel 369: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
370: my $result='';
1.37 albertel 371: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.36 albertel 372: &Apache::lonxml::startredirection;
373: } elsif ($target eq 'edit') {
374: my $descr=&Apache::lonxml::get_all_text('/text',$parser);
375: $result=&Apache::edit::tag_start($target,$token,'Task Description').
376: &Apache::edit::editfield($token->[1],$descr,'Text',60,2).
377: &Apache::edit::end_row();
378: } elsif ($target eq "modified") {
1.39 albertel 379: $result=$token->[4].&Apache::edit::modifiedfield('/text',$parser);
1.36 albertel 380: }
381: return $result;
1.1 albertel 382: }
383:
384: sub end_text {
1.36 albertel 385: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
386: my $result;
1.37 albertel 387: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.36 albertel 388: my $name = $Apache::imageresponse::curname;
389: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 390: #&& !&Apache::response::showallfoils()
391: ) {
1.36 albertel 392: $Apache::response::conceptgroup{"$name.text"} = &Apache::lonxml::endredirection;
393: } else {
394: $Apache::response::foilgroup{"$name.text"} = &Apache::lonxml::endredirection;
395: }
396: } elsif ($target eq 'edit') {
397: $result=&Apache::edit::end_table();
398: }
399: return $result;
1.1 albertel 400: }
401:
402: sub start_image {
1.36 albertel 403: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
404: my $result='';
1.37 albertel 405: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.36 albertel 406: &Apache::lonxml::startredirection;
407: } elsif ($target eq 'edit') {
408: my $bgimg=&Apache::lonxml::get_all_text('/image',$parser);
409: $Apache::edit::bgimgsrc=$bgimg;
410: $Apache::edit::bgimgsrcdepth=$Apache::lonxml::curdepth;
411:
412: $result=&Apache::edit::tag_start($target,$token,'Clickable Image').
413: &Apache::edit::editline($token->[1],$bgimg,'Image Source File',40);
414: $result.=&Apache::edit::browse(undef,'textnode').' ';
415: $result.=&Apache::edit::search(undef,'textnode').
416: &Apache::edit::end_row();
417: } elsif ($target eq "modified") {
1.39 albertel 418: $result=$token->[4].&Apache::edit::modifiedfield('/image',$parser);
1.36 albertel 419: }
420: return $result;
1.1 albertel 421: }
422:
423: sub end_image {
1.36 albertel 424: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
425: my $result;
426: my $name = $Apache::imageresponse::curname;
427: if ($target eq 'web') {
428: my $image = &Apache::lonxml::endredirection;
429: &Apache::lonxml::debug("original image is $image");
1.37 albertel 430: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 431: #&& !&Apache::response::showallfoils()
432: ) {
1.37 albertel 433: $Apache::response::conceptgroup{"$name.image"} = $image;
434: } else {
435: $Apache::response::foilgroup{"$name.image"} = $image;
436: }
437: } elsif ($target eq 'analyze') {
438: my $image = &Apache::lonxml::endredirection;
1.36 albertel 439: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 440: #&& !&Apache::response::showallfoils()
441: ) {
1.36 albertel 442: $Apache::response::conceptgroup{"$name.image"} = $image;
443: } else {
444: $Apache::response::foilgroup{"$name.image"} = $image;
445: }
446: } elsif ($target eq 'edit') {
447: $result=&Apache::edit::end_table();
448: } elsif ($target eq 'tex') {
449: my $src = &Apache::lonxml::endredirection;
450: $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
451: my $width_param = '';
452: my $height_param = '';
453: my $scaling = .3;
454: my $image = Image::Magick->new;
455: my $current_figure = $image->Read($src);
456: $width_param = $image->Get('width') * $scaling;;
457: $height_param = $image->Get('height') * $scaling;;
458: undef $image;
459: my $epssrc = $src;
460: $epssrc =~ s/(\.gif|\.jpg)$/\.eps/i;
461: if (not -e $epssrc) {
462: my $localfile = $epssrc;
463: $localfile =~ s/.*(\/res)/$1/;
464: my $file;
465: my $path;
466: if ($localfile =~ m!(.*)/([^/]*)$!) {
467: $file = $2;
468: $path = $1.'/';
469: }
470: my $signal_eps = 0;
471: my @content_directory = &Apache::lonnet::dirlist($path);
472: for (my $iy=0;$iy<=$#content_directory;$iy++) {
473: my @tempo_array = split(/&/,$content_directory[$iy]);
474: $content_directory[$iy] = $tempo_array[0];
475: if ($file eq $tempo_array[0]) {
476: $signal_eps = 1;
477: last;
478: }
479: }
480: if ($signal_eps) {
481: my $eps_file = &Apache::lonnet::getfile($localfile);
482: } else {
483: $localfile = $src;
484: $localfile =~ s/.*(\/res)/$1/;
485: my $as = &Apache::lonnet::getfile($src);
486: }
487: }
1.19 sakharuk 488: my $file;
489: my $path;
1.36 albertel 490: if ($src =~ m!(.*)/([^/]*)$!) {
1.19 sakharuk 491: $file = $2;
492: $path = $1.'/';
1.36 albertel 493: }
494: my $newsrc = $src;
495: $newsrc =~ s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;
496: $file=~s/(\.gif|\.jpg|\.jpeg)$/\.eps/i;
497: #do we have any specified size of the picture?
498: my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval);
499: my $TeXheight = &Apache::lonxml::get_param('TeXheight',$parstack,$safeeval);
500: my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval);
501: if ($TeXwidth ne '') {
502: $width_param = $TeXwidth;
503: } elsif ($TeXheight ne '') {
504: $width_param = $TeXheight/$height_param*$width_param;
505: } elsif ($width ne '') {
506: $width_param = $width*$scaling;
507: }
1.55 albertel 508: $width_param=&Apache::randomlabel::adjust_textwidth($width_param);
1.36 albertel 509: #where can we find the picture?
510: if (-e $newsrc) {
511: if ($path) {
512: $Apache::response::foilgroup{"$name.image"} ='\vskip 0 mm \noindent\graphicspath{{'.$path.'}}\includegraphics[width='.$width_param.' mm]{'.$file.'} ';
1.19 sakharuk 513: }
514: } else {
1.46 sakharuk 515: #care about eps dynamical generation
516: $Apache::response::foilgroup{"$name.image"}='\vskip 0 mm '.&Apache::londefdef::eps_generation($src,$file,$width_param);
1.19 sakharuk 517: }
1.36 albertel 518: }
519: return $result;
1.1 albertel 520: }
521:
522: sub start_rectangle {
1.36 albertel 523: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
524: my $result='';
1.38 albertel 525: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
526: $target eq 'analyze') {
1.36 albertel 527: &Apache::lonxml::startredirection;
528: } elsif ($target eq 'edit') {
529: my $coords=&Apache::lonxml::get_all_text('/rectangle',$parser);
530: $result=&Apache::edit::tag_start($target,$token,'Rectangle').
531: &Apache::edit::editline($token->[1],$coords,'Coordinate Pairs',40).
1.44 albertel 532: &Apache::edit::entercoord(undef,'textnode',undef,undef,'box').
1.36 albertel 533: &Apache::edit::end_row();
534: } elsif ($target eq "modified") {
1.44 albertel 535: &Apache::edit::deletecoorddata();
1.39 albertel 536: $result=$token->[4].&Apache::edit::modifiedfield('/rectangle',$parser);
1.36 albertel 537: }
538: return $result;
1.1 albertel 539: }
540:
1.3 albertel 541: sub grade_rectangle {
1.36 albertel 542: my ($spec,$x,$y) = @_;
543: &Apache::lonxml::debug("Spec is $spec");
1.43 albertel 544: my ($x1,$y1,$x2,$y2)=($spec=~m/rectangle:\(([0-9]+),([0-9]+)\)\-\(([0-9]+),([0-9]+)\)/);
1.36 albertel 545: &Apache::lonxml::debug("Point $x1,$y1,$x2,$y2");
546: if ($x1 > $x2) { my $temp=$x1;$x1=$x2;$x2=$temp; }
547: if ($y1 > $y2) { my $temp=$y1;$y1=$y2;$y2=$temp; }
548: if (($x >= $x1) && ($x <= $x2) && ($y >= $y1) && ($y <= $y2)) {
549: return 'APPROX_ANS';
550: }
551: return 'INCORRECT';
1.3 albertel 552: }
553:
1.1 albertel 554: sub end_rectangle {
1.36 albertel 555: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
556: my $result;
1.38 albertel 557: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
558: $target eq 'analyze') {
1.36 albertel 559: my $name = $Apache::imageresponse::curname;
560: my $area = &Apache::lonxml::endredirection;
1.54 albertel 561: $area=~s/\s//g;
1.36 albertel 562: &Apache::lonxml::debug("out is $area for $name");
563: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 564: #&& !&Apache::response::showallfoils()
565: ) {
1.36 albertel 566: push @{ $Apache::response::conceptgroup{"$name.area"} },"rectangle:$area";
567: } else {
568: push @{ $Apache::response::foilgroup{"$name.area"} },"rectangle:$area";
1.43 albertel 569: }
570: } elsif ($target eq 'edit') {
571: $result=&Apache::edit::end_table();
572: }
573: return $result;
574: }
575:
576: sub start_polygon {
577: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
578: my $result='';
579: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
580: $target eq 'analyze') {
581: &Apache::lonxml::startredirection;
582: } elsif ($target eq 'edit') {
583: my $coords=&Apache::lonxml::get_all_text('/polygon',$parser);
584: $result=&Apache::edit::tag_start($target,$token,'Polygon').
585: &Apache::edit::editline($token->[1],$coords,'Coordinate list',40).
1.44 albertel 586: &Apache::edit::entercoord(undef,'textnode',undef,undef,'polygon').
1.43 albertel 587: &Apache::edit::end_row();
588: } elsif ($target eq "modified") {
589: $result=$token->[4].&Apache::edit::modifiedfield('/polygon',$parser);
590: }
591: return $result;
592: }
593:
594: sub grade_polygon {
595: my ($spec,$x,$y) = @_;
596: &Apache::lonxml::debug("Spec is $spec");
597: $spec=~s/^polygon://;
598: my @polygon;
599: foreach my $coord (split('-',$spec)) {
600: my ($x,$y)=($coord=~m/\(([0-9]+),([0-9]+)\)/);
601: &Apache::lonxml::debug("x $x y $y");
602: push @polygon, {'x'=>$x,'y'=>$y};
603: }
604: #make end point start point
605: push @polygon, $polygon[0];
606: # cribbed from
607: # http://geometryalgorithms.com/Archive/algorithm_0103/algorithm_0103.htm
608: my $crossing = 0; # the crossing number counter
609:
610: # loop through all edges of the polygon
611: for (my $i=0; $i<$#polygon; $i++) { # edge from V[i] to V[i+1]
612: if ((($polygon[$i]->{'y'} <= $y)
613: && ($polygon[$i+1]->{'y'} > $y)) # an upward crossing
614: ||
615: (($polygon[$i]->{'y'} > $y)
616: && ($polygon[$i+1]->{'y'} <= $y))) { # a downward crossing
617: # compute the actual edge-ray intersect x-coordinate
618: my $vt = ($y - $polygon[$i]->{'y'})
619: / ($polygon[$i+1]->{'y'} - $polygon[$i]->{'y'});
620: if ($x < $polygon[$i]->{'x'} + $vt *
621: ($polygon[$i+1]->{'x'} - $polygon[$i]->{'x'})) { # x<intersect
622: $crossing++; # a valid crossing of y=P.y right of P.x
623: }
624: }
625: }
626:
627: # 0 if even (out), and 1 if odd (in)
628: if ($crossing%2) {
629: return 'APPROX_ANS';
630: } else {
631: return 'INCORRECT';
632: }
633: }
634:
635: sub end_polygon {
636: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
637: my $result;
638: if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' ||
639: $target eq 'analyze') {
640: my $name = $Apache::imageresponse::curname;
641: my $area = &Apache::lonxml::endredirection;
1.48 albertel 642: $area=~s/\s*//g;
1.43 albertel 643: &Apache::lonxml::debug("out is $area for $name");
644: if ( $Apache::imageresponse::conceptgroup
1.56 albertel 645: #&& !&Apache::response::showallfoils()
646: ) {
1.43 albertel 647: push @{ $Apache::response::conceptgroup{"$name.area"} },"polygon:$area";
648: } else {
649: push @{ $Apache::response::foilgroup{"$name.area"} },"polygon:$area";
1.36 albertel 650: }
651: } elsif ($target eq 'edit') {
652: $result=&Apache::edit::end_table();
653: }
654: return $result;
1.1 albertel 655: }
656: 1;
657: __END__
658:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>