source: grass/trunk/display/d.rast.arrow/main.c

Last change on this file was 66382, checked in by hcho, 9 years ago

d.rast.arrow: Added the Drainage aspect type (r.watershed drainage= output)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id
  • Property svn:mime-type set to text/x-csrc
File size: 19.9 KB
Line 
1/*
2 ****************************************************************************
3 *
4 * MODULE: d.rast.arrow
5 * AUTHOR(S): Chris Rewerts, Agricultural Engineering, Purdue University
6 * PURPOSE: Draw arrows on slope/aspect maps.
7 * COPYRIGHT: (C) 2000, 2010 by the GRASS Development Team
8 *
9 * This program is free software under the GNU General Public
10 * License (>=v2). Read the file COPYING that comes with GRASS
11 * for details.
12 *
13 *****************************************************************************/
14
15/* some minor cleanup done by Andreas Lange, andreas.lange@rhein-main.de
16 * Update to handle NULLs and floating point aspect maps: Hamish Bowman, Aug 2004
17 * Update for 360 degree arrows and magnitude scaling: Hamish Bowman, Oct 2005
18 * Align grids with raster cells: Huidae Cho, Apr 2009
19 * Drainage aspect type: Huidae Cho, Sep 2015
20 */
21
22/*
23 * Chris Rewerts, Agricultural Engineering, Purdue University
24 * rewerts@ecn.purdue.edu March 1991
25 *
26 * d.rast.arrow
27 *
28 * Usage: d.rast.arrow
29 *
30 * This program used Dgrid's sources as a beginning. Purpose of Darrow
31 * is to read an aspect layer produced by slope.aspect or by the
32 * programs created for the ANSWERS or AGNPS Hydrology Toolbox
33 * endeavors. d.rast.arrow draws an arrow on the graphic display
34 * of each cell, so that the flow pattern computed as an aspect
35 * layer can be easily seen. Other symbols ("?", "X") may be drawn
36 * as needed.
37 */
38
39#include <stdlib.h>
40#include <string.h>
41#include <math.h>
42#include <grass/gis.h>
43#include <grass/raster.h>
44#include <grass/display.h>
45#include <grass/colors.h>
46#include <grass/glocale.h>
47
48# define RpD ((2 * M_PI) / 360.) /* radians/degree */
49# define D2R(d) (double)(d * RpD) /* degrees->radians */
50
51static void arrow_mag(double, double);
52static void arrow_360(double);
53static void arrow_se(void);
54static void arrow_ne(void);
55static void arrow_nw(void);
56static void arrow_sw(void);
57static void arrow_e(void);
58static void arrow_w(void);
59static void arrow_s(void);
60static void arrow_n(void);
61static void draw_x(void);
62static void unknown_(void);
63
64static char *layer_name;
65static int map_type, arrow_color, grid_color, x_color, unknown_color;
66static int row, col;
67
68int main(int argc, char **argv)
69{
70 struct Cell_head window;
71 RASTER_MAP_TYPE raster_type, mag_raster_type = -1;
72 int layer_fd;
73 void *raster_row, *ptr;
74 int nrows, ncols;
75 int aspect_c = -1;
76 float aspect_f = -1.0;
77
78 double scale;
79 int skip, no_arrow;
80 char *mag_map = NULL;
81 void *mag_raster_row = NULL, *mag_ptr = NULL;
82 double length = -1;
83 int mag_fd = -1;
84 struct FPRange range;
85 double mag_min, mag_max;
86
87 struct GModule *module;
88 struct Option *opt1, *opt2, *opt3, *opt4, *opt5,
89 *opt6, *opt7, *opt8, *opt9;
90 struct Flag *align;
91
92 double t, b, l, r;
93
94 G_gisinit(argv[0]);
95
96 module = G_define_module();
97 G_add_keyword(_("display"));
98 G_add_keyword(_("map annotations"));
99 G_add_keyword(_("raster"));
100 module->description =
101 _("Draws arrows representing cell aspect direction "
102 "for a raster map containing aspect data.");
103
104 opt1 = G_define_standard_option(G_OPT_R_MAP);
105 opt1->description = _("Name of raster aspect map to be displayed");
106
107 opt2 = G_define_option();
108 opt2->key = "type";
109 opt2->type = TYPE_STRING;
110 opt2->required = NO;
111 opt2->answer = "grass";
112 opt2->options = "grass,compass,drainage,agnps,answers";
113 opt2->description = _("Type of existing raster aspect map");
114
115 opt3 = G_define_standard_option(G_OPT_C);
116 opt3->key = "color";
117 opt3->answer = "green";
118 opt3->label = _("Color for drawing arrows");
119 opt3->guisection = _("Colors");
120
121 opt4 = G_define_standard_option(G_OPT_CN);
122 opt4->key = "grid_color";
123 opt4->answer = "gray";
124 opt4->label = _("Color for drawing drawing grid");
125 opt4->guisection = _("Colors");
126
127 opt5 = G_define_standard_option(G_OPT_CN);
128 opt5->key = "null_color";
129 opt5->answer = DEFAULT_FG_COLOR;
130 opt5->label = _("Color for drawing null values (X symbol)");
131 opt5->guisection = _("Colors");
132
133 opt6 = G_define_standard_option(G_OPT_CN);
134 opt6->key = "unknown_color";
135 opt6->answer = "red";
136 opt6->label = _("Color for showing unknown information (? symbol)");
137 opt6->guisection = _("Colors");
138
139 opt9 = G_define_option();
140 opt9->key = "skip";
141 opt9->type = TYPE_INTEGER;
142 opt9->required = NO;
143 opt9->answer = "1";
144 opt9->description = _("Draw arrow every Nth grid cell");
145
146 opt7 = G_define_option();
147 opt7->key = "magnitude_map";
148 opt7->type = TYPE_STRING;
149 opt7->required = NO;
150 opt7->multiple = NO;
151 opt7->gisprompt = "old,cell,raster";
152 opt7->description =
153 _("Raster map containing values used for arrow length");
154
155 opt8 = G_define_option();
156 opt8->key = "scale";
157 opt8->type = TYPE_DOUBLE;
158 opt8->required = NO;
159 opt8->answer = "1.0";
160 opt8->description = _("Scale factor for arrows (magnitude map)");
161
162 align = G_define_flag();
163 align->key = 'a';
164 align->description = _("Align grids with raster cells");
165
166
167 /* Check command line */
168 if (G_parser(argc, argv))
169 exit(EXIT_FAILURE);
170
171
172 layer_name = opt1->answer;
173
174 arrow_color = D_translate_color(opt3->answer);
175
176 /* Convert none (transparent) to -1 which in this module means
177 that we will not draw things having this color (-1).
178 We don't do that for arrow because we always want them.
179 (This is specified by the gisprompt ('type') of the options.)
180 */
181 if (strcmp("none", opt4->answer) == 0)
182 grid_color = -1;
183 else
184 grid_color = D_translate_color(opt4->answer);
185
186 if (strcmp("none", opt5->answer) == 0)
187 x_color = -1;
188 else
189 x_color = D_translate_color(opt5->answer);
190
191 if (strcmp("none", opt6->answer) == 0)
192 unknown_color = -1;
193 else
194 unknown_color = D_translate_color(opt6->answer);
195
196 if (strcmp("grass", opt2->answer) == 0)
197 map_type = 1;
198 else if (strcmp("agnps", opt2->answer) == 0)
199 map_type = 2;
200 else if (strcmp("answers", opt2->answer) == 0)
201 map_type = 3;
202 else if (strcmp("compass", opt2->answer) == 0)
203 map_type = 4;
204 else if (strcmp("drainage", opt2->answer) == 0)
205 map_type = 5;
206
207
208 scale = atof(opt8->answer);
209 if (scale <= 0.0)
210 G_fatal_error(_("Illegal value for scale factor"));
211
212 skip = atoi(opt9->answer);
213 if (skip <= 0)
214 G_fatal_error(_("Illegal value for skip factor"));
215
216
217 if (opt7->answer) {
218 if (map_type != 1 && map_type != 4)
219 G_fatal_error(_("Magnitude is only supported for GRASS and compass aspect maps."));
220
221 mag_map = opt7->answer;
222 }
223 else if (scale != 1.0)
224 G_warning(_("Scale option requires magnitude_map"));
225
226
227 /* Setup driver and check important information */
228 D_open_driver();
229
230 D_setup(0);
231
232 /* Read in the map window associated with window */
233 G_get_window(&window);
234
235 if (align->answer) {
236 struct Cell_head wind;
237
238 Rast_get_cellhd(layer_name, "", &wind);
239
240 /* expand window extent by one wind resolution */
241 wind.west += wind.ew_res * ((int)((window.west - wind.west) / wind.ew_res) - (window.west < wind.west));
242 wind.east += wind.ew_res * ((int)((window.east - wind.east) / wind.ew_res) + (window.east > wind.east));
243 wind.south += wind.ns_res * ((int)((window.south - wind.south) / wind.ns_res) - (window.south < wind.south));
244 wind.north += wind.ns_res * ((int)((window.north - wind.north) / wind.ns_res) + (window.north > wind.north));
245
246 wind.rows = (wind.north - wind.south) / wind.ns_res;
247 wind.cols = (wind.east - wind.west) / wind.ew_res;
248
249 Rast_set_window(&wind);
250
251 nrows = wind.rows;
252 ncols = wind.cols;
253
254 t = (wind.north - window.north) * nrows / (wind.north - wind.south);
255 b = t + (window.north - window.south) * nrows / (wind.north - wind.south);
256 l = (window.west - wind.west) * ncols / (wind.east - wind.west);
257 r = l + (window.east - window.west) * ncols / (wind.east - wind.west);
258 } else {
259 nrows = window.rows;
260 ncols = window.cols;
261
262 t = 0;
263 b = nrows;
264 l = 0;
265 r = ncols;
266 }
267
268 D_set_src(t, b, l, r);
269 D_update_conversions();
270
271 /* figure out arrow scaling if using a magnitude map */
272 if (opt7->answer) {
273 Rast_init_fp_range(&range); /* really needed? */
274 if (Rast_read_fp_range(mag_map, "", &range) != 1)
275 G_fatal_error(_("Problem reading range file"));
276 Rast_get_fp_range_min_max(&range, &mag_min, &mag_max);
277
278 scale *= 1.5 / fabs(mag_max);
279 G_debug(3, "scaling=%.2f rast_max=%.2f", scale, mag_max);
280 }
281
282 if (grid_color > 0) { /* ie not "none" */
283 /* Set color */
284 D_use_color(grid_color);
285
286 /* Draw vertical grids */
287 for (col = 0; col < ncols; col++)
288 D_line_abs(col, 0, col, nrows);
289
290 /* Draw horizontal grids */
291 for (row = 0; row < nrows; row++)
292 D_line_abs(0, row, ncols, row);
293 }
294
295 /* open the raster map */
296 layer_fd = Rast_open_old(layer_name, "");
297
298 raster_type = Rast_get_map_type(layer_fd);
299
300 /* allocate the cell array */
301 raster_row = Rast_allocate_buf(raster_type);
302
303
304 if (opt7->answer) {
305 /* open the magnitude raster map */
306 mag_fd = Rast_open_old(mag_map, "");
307
308 mag_raster_type = Rast_get_map_type(mag_fd);
309
310 /* allocate the cell array */
311 mag_raster_row = Rast_allocate_buf(mag_raster_type);
312 }
313
314
315 /* loop through cells, find value, determine direction (n,s,e,w,ne,se,sw,nw),
316 and call appropriate function to draw an arrow on the cell */
317
318 for (row = 0; row < nrows; row++) {
319 Rast_get_row(layer_fd, raster_row, row, raster_type);
320 ptr = raster_row;
321
322 if (opt7->answer) {
323 Rast_get_row(mag_fd, mag_raster_row, row, mag_raster_type);
324 mag_ptr = mag_raster_row;
325 }
326
327 for (col = 0; col < ncols; col++) {
328
329 if (row % skip != 0)
330 no_arrow = TRUE;
331 else
332 no_arrow = FALSE;
333
334 if (col % skip != 0)
335 no_arrow = TRUE;
336
337 /* find aspect direction based on cell value */
338 if (raster_type == CELL_TYPE)
339 aspect_f = *((CELL *) ptr);
340 else if (raster_type == FCELL_TYPE)
341 aspect_f = *((FCELL *) ptr);
342 else if (raster_type == DCELL_TYPE)
343 aspect_f = *((DCELL *) ptr);
344
345
346 if (opt7->answer) {
347
348 if (mag_raster_type == CELL_TYPE)
349 length = *((CELL *) mag_ptr);
350 else if (mag_raster_type == FCELL_TYPE)
351 length = *((FCELL *) mag_ptr);
352 else if (mag_raster_type == DCELL_TYPE)
353 length = *((DCELL *) mag_ptr);
354
355 length *= scale;
356
357 if (Rast_is_null_value(mag_ptr, mag_raster_type)) {
358 G_debug(5, "Invalid arrow length [NULL]. Skipping.");
359 no_arrow = TRUE;
360 }
361 else if (length <= 0.0) { /* use fabs() or theta+=180? */
362 G_debug(5, "Illegal arrow length [%.3f]. Skipping.",
363 length);
364 no_arrow = TRUE;
365 }
366 }
367
368 if (no_arrow) {
369 ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type));
370 if (opt7->answer)
371 mag_ptr =
372 G_incr_void_ptr(mag_ptr,
373 Rast_cell_size(mag_raster_type));
374 no_arrow = FALSE;
375 continue;
376 }
377
378 /* treat AGNPS and ANSWERS data like old zero-as-null CELL */
379 /* TODO: update models */
380 if (map_type == 2 || map_type == 3 || map_type == 5) {
381 if (Rast_is_null_value(ptr, raster_type))
382 aspect_c = 0;
383 else
384 aspect_c = (int)(aspect_f + 0.5);
385 }
386
387
388 /** Now draw the arrows **/
389
390 /* case switch for standard GRASS aspect map
391 measured in degrees counter-clockwise from east */
392 if (map_type == 1) {
393 D_use_color(arrow_color);
394
395 if (Rast_is_null_value(ptr, raster_type)) {
396 /* don't draw anything if x_color is none (transparent) */
397 if (x_color > 0) {
398 D_use_color(x_color);
399 draw_x();
400 D_use_color(arrow_color);
401 }
402 }
403 else if (aspect_f >= 0.0 && aspect_f <= 360.0) {
404 if (opt7->answer)
405 arrow_mag(aspect_f, length);
406 else
407 arrow_360(aspect_f);
408 }
409 else if (unknown_color > 0) {
410 /* don't draw if unknown_color is none (transparent) */
411 D_use_color(unknown_color);
412 unknown_();
413 D_use_color(arrow_color);
414 }
415 }
416
417
418 /* case switch for AGNPS type aspect map */
419 else if (map_type == 2) {
420 D_use_color(arrow_color);
421 switch (aspect_c) {
422 case 0:
423 /* only draw if x_color is not none (transparent) */
424 if (x_color > 0) {
425 D_use_color(x_color);
426 draw_x();
427 D_use_color(arrow_color);
428 }
429 break;
430 case 1:
431 arrow_n();
432 break;
433 case 2:
434 arrow_ne();
435 break;
436 case 3:
437 arrow_e();
438 break;
439 case 4:
440 arrow_se();
441 break;
442 case 5:
443 arrow_s();
444 break;
445 case 6:
446 arrow_sw();
447 break;
448 case 7:
449 arrow_w();
450 break;
451 case 8:
452 arrow_nw();
453 break;
454 default:
455 /* only draw if unknown_color is not none */
456 if (unknown_color > 0) {
457 D_use_color(unknown_color);
458 unknown_();
459 D_use_color(arrow_color);
460 }
461 break;
462 }
463 }
464
465
466 /* case switch for ANSWERS type aspect map */
467 else if (map_type == 3) {
468 D_use_color(arrow_color);
469 if (aspect_c >= 15 && aspect_c <= 360) /* start at zero? */
470 arrow_360((double)aspect_c);
471 else if (aspect_c == 400) {
472 if (unknown_color > 0) {
473 /* only draw if unknown_color is not none */
474 D_use_color(unknown_color);
475 unknown_();
476 D_use_color(arrow_color);
477 }
478 }
479 else if (x_color > 0) {
480 /* only draw if x_color is not none (transparent) */
481 D_use_color(x_color);
482 draw_x();
483 D_use_color(arrow_color);
484 }
485 }
486
487 /* case switch for compass type aspect map
488 measured in degrees clockwise from north */
489 else if (map_type == 4) {
490 D_use_color(arrow_color);
491
492 if (Rast_is_null_value(ptr, raster_type)) {
493 if (x_color > 0) {
494 /* only draw if x_color is not none */
495 D_use_color(x_color);
496 draw_x();
497 D_use_color(arrow_color);
498 }
499 }
500 else if (aspect_f >= 0.0 && aspect_f <= 360.0) {
501 if (opt7->answer)
502 arrow_mag(90 - aspect_f, length);
503 else
504 arrow_360(90 - aspect_f);
505 }
506 else if (unknown_color > 0) {
507 /* only draw if unknown_color is not none */
508 D_use_color(unknown_color);
509 unknown_();
510 D_use_color(arrow_color);
511 }
512 }
513
514 /* case switch for r.watershed drainage type aspect map */
515 else if (map_type == 5) {
516 D_use_color(arrow_color);
517 switch (aspect_c >= 0 ? aspect_c : -aspect_c) {
518 case 0:
519 /* only draw if x_color is not none (transparent) */
520 if (x_color > 0) {
521 D_use_color(x_color);
522 draw_x();
523 D_use_color(arrow_color);
524 }
525 break;
526 case 1:
527 arrow_ne();
528 break;
529 case 2:
530 arrow_n();
531 break;
532 case 3:
533 arrow_nw();
534 break;
535 case 4:
536 arrow_w();
537 break;
538 case 5:
539 arrow_sw();
540 break;
541 case 6:
542 arrow_s();
543 break;
544 case 7:
545 arrow_se();
546 break;
547 case 8:
548 arrow_e();
549 break;
550 default:
551 /* only draw if unknown_color is not none */
552 if (unknown_color > 0) {
553 D_use_color(unknown_color);
554 unknown_();
555 D_use_color(arrow_color);
556 }
557 break;
558 }
559 }
560
561 ptr = G_incr_void_ptr(ptr, Rast_cell_size(raster_type));
562 if (opt7->answer)
563 mag_ptr =
564 G_incr_void_ptr(mag_ptr, Rast_cell_size(mag_raster_type));
565 }
566 }
567
568 Rast_close(layer_fd);
569 if (opt7->answer)
570 Rast_close(mag_fd);
571
572 D_save_command(G_recreate_command());
573 D_close_driver();
574
575 exit(EXIT_SUCCESS);
576}
577
578/* --- end of main --- */
579
580/*---------------------------------------------------------------*/
581
582
583static void arrow_mag(double theta, double length)
584{ /* angle is measured in degrees counter-clockwise from east */
585 double x, y, dx, dy, mid_x, mid_y;
586 double theta_offset;
587
588 theta *= -1; /* display coords use inverse y */
589
590 /* find the display coordinates of the middle of the cell */
591 mid_x = col + (.5);
592 mid_y = row + (.5);
593
594 D_begin();
595
596 /* tail */
597 D_move_abs(mid_x, mid_y);
598
599 /* head */
600 x = mid_x + (length * cos(D2R(theta)));
601 y = mid_y + (length * sin(D2R(theta)));
602 D_cont_abs(x, y);
603
604 /* fin 1 */
605 theta_offset = theta + 20;
606 dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
607 dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
608 D_cont_abs(dx, dy);
609
610 /* fin 2 */
611 D_move_abs(x, y);
612 theta_offset = theta - 20;
613 dx = mid_x + (0.6 * length * cos(D2R(theta_offset)));
614 dy = mid_y + (0.6 * length * sin(D2R(theta_offset)));
615 D_cont_abs(dx, dy);
616
617 D_end();
618 D_stroke();
619}
620
621
622static void arrow_360(double theta)
623{ /* angle is measured in degrees counter-clockwise from east */
624 double x, y, dx, dy, mid_x, mid_y;
625 double max_radius, theta_offset;
626
627 theta *= -1; /* display coords use inverse y */
628 max_radius = 0.8 / 2;
629
630 /* find the display coordinates of the middle of the cell */
631 mid_x = col + (0.5);
632 mid_y = row + (0.5);
633
634 D_begin();
635
636 /* head */
637 x = mid_x + (max_radius * cos(D2R(theta)));
638 y = mid_y + (max_radius * sin(D2R(theta)));
639 D_move_abs(x, y);
640
641 /* tail */
642 dx = -2 * (max_radius * cos(D2R(theta)));
643 dy = -2 * (max_radius * sin(D2R(theta)));
644 D_cont_rel(dx, dy);
645
646 /* fin 1 */
647 D_move_abs(x, y);
648 theta_offset = theta + 90;
649 dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset)));
650 dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset)));
651 D_cont_abs(dx, dy);
652
653 /* fin 2 */
654 D_move_abs(x, y);
655 theta_offset = theta - 90;
656 dx = mid_x + (0.5 * max_radius * cos(D2R(theta_offset)));
657 dy = mid_y + (0.5 * max_radius * sin(D2R(theta_offset)));
658 D_cont_abs(dx, dy);
659
660 D_end();
661 D_stroke();
662}
663
664static void arrow_se(void)
665{
666 double x = col + (.8);
667 double y = row + (.8);
668 D_begin();
669 D_move_abs(x, y);
670 D_cont_rel(((-.6)), (((-.6))));
671 D_move_abs(x, y);
672 D_cont_rel(0, ((-.4)));
673 D_move_abs(x, y);
674 D_cont_rel(((-.4)), 0);
675 D_end();
676 D_stroke();
677}
678
679static void arrow_ne(void)
680{
681 double x = col + (.8);
682 double y = row + (.2);
683 D_begin();
684 D_move_abs(x, y);
685 D_cont_rel(((-.6)), (((.6))));
686 D_move_abs(x, y);
687 D_cont_rel(0, ((.4)));
688 D_move_abs(x, y);
689 D_cont_rel(((-.4)), 0);
690 D_end();
691 D_stroke();
692}
693
694static void arrow_nw(void)
695{
696 double x = col + (.2);
697 double y = row + (.2);
698 D_begin();
699 D_move_abs(x, y);
700 D_cont_rel(((.6)), (((.6))));
701 D_move_abs(x, y);
702 D_cont_rel(0, ((.4)));
703 D_move_abs(x, y);
704 D_cont_rel(((.4)), 0);
705 D_end();
706 D_stroke();
707}
708
709static void arrow_sw(void)
710{
711 double x = col + (.2);
712 double y = row + (.8);
713 D_begin();
714 D_move_abs(x, y);
715 D_cont_rel(((.6)), (((-.6))));
716 D_move_abs(x, y);
717 D_cont_rel(0, ((-.4)));
718 D_move_abs(x, y);
719 D_cont_rel(((.4)), 0);
720 D_end();
721 D_stroke();
722}
723
724static void arrow_e(void)
725{
726 double x = col + (.9);
727 double y = row + (.5);
728 D_begin();
729 D_move_abs(x, y);
730 D_cont_rel(((-.8)), 0);
731 D_move_abs(x, y);
732 D_cont_rel(((-.3)), ((-.3)));
733 D_move_abs(x, y);
734 D_cont_rel(((-.3)), ((.3)));
735 D_end();
736 D_stroke();
737}
738
739static void arrow_w(void)
740{
741 double x = col + (.1);
742 double y = row + (.5);
743 D_begin();
744 D_move_abs(x, y);
745 D_cont_rel(((.8)), 0);
746 D_move_abs(x, y);
747 D_cont_rel(((.3)), ((-.3)));
748 D_move_abs(x, y);
749 D_cont_rel(((.3)), ((.3)));
750 D_end();
751 D_stroke();
752}
753
754static void arrow_s(void)
755{
756 double x = col + (.5);
757 double y = row + (.9);
758 D_begin();
759 D_move_abs(x, y);
760 D_cont_rel(0, ((-.8)));
761 D_move_abs(x, y);
762 D_cont_rel(((.3)), ((-.3)));
763 D_move_abs(x, y);
764 D_cont_rel(((-.3)), ((-.3)));
765 D_end();
766 D_stroke();
767}
768
769static void arrow_n(void)
770{
771 double x = col + (.5);
772 double y = row + (.1);
773 D_begin();
774 D_move_abs(x, y);
775 D_cont_rel(0, ((.8)));
776 D_move_abs(x, y);
777 D_cont_rel(((.3)), ((.3)));
778 D_move_abs(x, y);
779 D_cont_rel(((-.3)), ((.3)));
780 D_end();
781 D_stroke();
782}
783
784static void draw_x(void)
785{
786 double x = col;
787 double y = row;
788 D_begin();
789 D_move_abs(x, y);
790 D_cont_rel(1, 1);
791 y = row + 1;
792 D_move_abs(x, y);
793 D_cont_rel(1, (-1));
794 D_end();
795 D_stroke();
796}
797
798static void unknown_(void)
799{
800 double x = col + (.3);
801 double y = row + (.4);
802
803 D_begin();
804 D_move_abs(x, y);
805 D_cont_rel(0, ((-.15)));
806 D_cont_rel(((.1)), ((-.1)));
807 D_cont_rel(((.2)), 0);
808 D_cont_rel(((.1)), ((.1)));
809 D_cont_rel(0, ((.2)));
810 D_cont_rel(((-.1)), ((.1)));
811 D_cont_rel(((-.1)), 0);
812 D_cont_rel(0, ((.25)));
813 D_move_rel(0, ((.1)));
814 D_cont_rel(0, ((.1)));
815 D_end();
816 D_stroke();
817}
Note: See TracBrowser for help on using the repository browser.