@@ -53,12 +53,12 @@ =head1 DESCRIPTION
5353
5454=head1 GRAPH OBJECTS
5555
56- There are eleven types of graph objects that the students can graph. Points, lines, circles,
57- parabolas, quadratics, cubics, intervals, sine waves, triangles, quadrilaterals and fills (or
58- shading of a region). The syntax for each of these objects to pass to the GraphTool constructor
59- is summarized as follows. Each object must be enclosed in braces. The first element in the
60- braces must be the name of the object. The following elements in the braces depend on the type
61- of element.
56+ There are several types of graph objects that the students can graph. Points, lines, circles,
57+ parabolas, quadratics, cubics, intervals, sine waves, triangles, quadrilaterals, vectors, and
58+ fills (or shading of a region). The syntax for each of these objects to pass to the GraphTool
59+ constructor is summarized as follows. Each object must be enclosed in braces. The first element
60+ in the braces must be the name of the object. The following elements in the braces depend on the
61+ type of element.
6262
6363For points the name "point" must be followed by the coordinates. For example:
6464
@@ -132,6 +132,12 @@ =head1 GRAPH OBJECTS
132132
133133 "{quadrilateral,solid,(0,0),(4,3),(2,3),(4,-3)}"
134134
135+ For vectors the name "vector" must be followed by the word "solid" or "dashed" to indicate if
136+ the vector is expected to be drawn solid or dashed. That is followed by the initial point and
137+ the terminal point. For example:
138+
139+ "{vector,solid,(0,0),(3,4)}"
140+
135141The student answers that are returned by the JavaScript will be a list of the list objects
136142discussed above and will be parsed by WeBWorK and passed to the checker as such. The default
137143checker is designed to grade the graph based on appearance. This means that if a student graphs
@@ -311,8 +317,8 @@ =head1 OPTIONS
311317The order the tools are listed here will also be the order the tools are presented in the graph
312318tool button box. In addition to the tools listed in the default options above, there is a
313319"PointTool", three point "QuadraticTool", four point "CubicTool", "IntervalTool",
314- "IncludeExcludePointTool", "SineWaveTool", "TriangleTool", and "QuadrilateralTool". Note that
315- the case of the tool names must match what is shown.
320+ "IncludeExcludePointTool", "SineWaveTool", "TriangleTool", "QuadrilateralTool", and
321+ "VectorTool". Note that the case of the tool names must match what is shown.
316322
317323=item staticObjects (Default: C<< staticObjects => [] >>)
318324
@@ -454,6 +460,7 @@ sub _parserGraphTool_init {
454460 ADD_JS_FILE(' js/GraphTool/sinewavetool.js' , 0, { defer => undef });
455461 ADD_JS_FILE(' js/GraphTool/triangle.js' , 0, { defer => undef });
456462 ADD_JS_FILE(' js/GraphTool/quadrilateral.js' , 0, { defer => undef });
463+ ADD_JS_FILE(' js/GraphTool/vector.js' , 0, { defer => undef });
457464
458465 return ;
459466}
@@ -1349,6 +1356,77 @@ sub addTools {
13491356 }
13501357 );
13511358 }
1359+ },
1360+ vector => {
1361+ js => ' graphTool.vectorTool.Vector' ,
1362+ tikz => {
1363+ code => sub {
1364+ my $gt = shift ;
1365+
1366+ my ($p1x , $p1y ) = @{ $_ -> {data }[2]{data } };
1367+ my ($p2x , $p2y ) = @{ $_ -> {data }[3]{data } };
1368+
1369+ if ($p1x == $p2x ) {
1370+ # Vertical vector
1371+ return (
1372+ " \\ draw[thick, blue, line width = 2.5pt, $_ ->{data}[1], *->] ($p1x , $p1y ) -- ($p2x , $p2y );\n " ,
1373+ [
1374+ " ($p1x ,$gt ->{bBox}[3]) -- ($p1x ,$gt ->{bBox}[1])"
1375+ . " -- ($gt ->{bBox}[2],$gt ->{bBox}[1]) -- ($gt ->{bBox}[2],$gt ->{bBox}[3]) -- cycle" ,
1376+ sub { return $_ [0] - $p1x ; }
1377+ ]
1378+ );
1379+ } else {
1380+ # Non-vertical vector
1381+ my $m = ($p2y - $p1y ) / ($p2x - $p1x );
1382+ my $y = sub { return $m * ($_ [0] - $p1x ) + $p1y ; };
1383+ return (
1384+ " \\ draw[thick, blue, line width = 2.5pt, $_ ->{data}[1], *->] ($p1x , $p1y ) -- ($p2x , $p2y );\n " ,
1385+ [
1386+ " ($gt ->{bBox}[0],"
1387+ . &$y ($gt -> {bBox }[0]) . ' ) -- '
1388+ . " ($gt ->{bBox}[2],"
1389+ . &$y ($gt -> {bBox }[2]) . ' )'
1390+ . " -- ($gt ->{bBox}[2],$gt ->{bBox}[1]) -- ($gt ->{bBox}[0],$gt ->{bBox}[1]) -- cycle" ,
1391+ sub { return $_ [1] - &$y ($_ [0]); }
1392+ ]
1393+ );
1394+ }
1395+ }
1396+ },
1397+ cmp => sub {
1398+ my ($vector ) = @_ ;
1399+
1400+ my $solid_dashed = $vector -> {data }[1];
1401+ my $initial_point = $vector -> {data }[2];
1402+ my $terminal_point = $vector -> {data }[3];
1403+
1404+ # These are the coefficients a, b, and c in ax + by + c = 0.
1405+ my @stdform = (
1406+ $vector -> {data }[2]{data }[1] - $vector -> {data }[3]{data }[1],
1407+ $vector -> {data }[3]{data }[0] - $vector -> {data }[2]{data }[0],
1408+ $vector -> {data }[2]{data }[0] * $vector -> {data }[3]{data }[1] -
1409+ $vector -> {data }[3]{data }[0] * $vector -> {data }[2]{data }[1]
1410+ );
1411+
1412+ my $vectorPointCmp = sub {
1413+ my $point = shift ;
1414+ my ($x , $y ) = $point -> value;
1415+ return $stdform [0] * $x + $stdform [1] * $y + $stdform [2] <=> 0;
1416+ };
1417+
1418+ return (
1419+ $vectorPointCmp ,
1420+ sub {
1421+ my ($other , $fuzzy ) = @_ ;
1422+ return
1423+ $other -> {data }[0] eq ' vector'
1424+ && ($fuzzy || $other -> {data }[1] eq $solid_dashed )
1425+ && $initial_point == $other -> {data }[2]
1426+ && $terminal_point == $other -> {data }[3];
1427+ }
1428+ );
1429+ }
13521430 }
13531431);
13541432
@@ -1367,6 +1445,8 @@ sub addTools {
13671445 TriangleTool => ' graphTool.triangleTool.TriangleTool' ,
13681446 # A quadrilateral tool.
13691447 QuadrilateralTool => ' graphTool.quadrilateralTool.QuadrilateralTool' ,
1448+ # A vector tool.
1449+ VectorTool => ' graphTool.vectorTool.VectorTool' ,
13701450 # Include/Exclude point tool.
13711451 IncludeExcludePointTool => ' graphTool.includeExcludePointTool.IncludeExcludePointTool' ,
13721452);
0 commit comments