/* TEACH GO_ROUNDLINES                           Ben Rabau, 11th Sep 1992


This teach file tries to give a number of examples of go_rounding lines
in the LIB * RC_GRAPHIC.

It basically tries to round the corner of two lines with a given
go_radius. If the go_radius is to big, a smaller one is used. If the
lines are under a too sharp go_angle, no go_rounding is performed. The
go_rounding will never take more than half the line's length to allow
the same procedure to be used on the other side of the line, for example
to produce oblong rectangles.

Some polylines are shown below, they can be either open or go_closed.
Note that for larger line-widths, the capStyle CapRound gives the best
results (see REF * XpwGraphic).

For more detailed information on the calculations used in this library
see LIB * GO_ROUNDLINES

See HELP * RC_GRAPHIC for more details on the environment.
 */

;;; To load the library please do:
uses go_polygon;
uses go_roundlines;

;;; It also requires an active go_pane (see TEACH * GO_PANE):
go_init_rc();

/*
-- SETS OF TWO ROUNDED LINES ------------------------------------------
 */
;;; We don't really want to create a high number of polygons just to
;;; show some of the rounding possibilities between two lines. Therefore
;;; we just create a dummy polygon which will serve as bases for all
;;; drawings:
vars dummy_polygon = newgo_polygon();

;;; Routine that draws one set of two rounded lines
define draw_round_lines( x1, y1, x0, y0, x2, y2, r );
lvars x1, y1, x0, y0, x2, y2, r;
lvars x01, y01, x02, y02, ArcList, SegList;
lvars pane = go_default_pane, poly = dummy_polygon;
    go_get_round_lines( x1, y1, x0, y0, x2, y2, r, pane, poly )
    -> (ArcList, SegList) ;

    go_transxyout( x2, y2, pane ) -> (x2, y2) ;
    go_transxyout( x1, y1, pane ) -> (x1, y1) ;
    explode( SegList ) -> (x01, y01, x02, y02) ;

    unless ( ArcList = [] ) then
        go_draw_arcs( pane,  ArcList );
    endunless;
    go_draw_line_segments( pane, [% x1, y1, x01, y01, x2, y2, x02, y02 %]);
enddefine;

;;; To see most possible rounded lines type: check_lines();
;;; (can be combined with check_orient)
define check_line( x, y );
lvars x, y, n;
   for n from -150 by 30 to 90 do
       draw_round_lines( n+2*x,n+y, x, y, n+x, n+2*y, 10 );
   endfor
enddefine;

define check_lines();
lvars x, y;
    go_clear( go_default_pane );
    check_line( 100, 100);
    check_line(-100, 100);
    check_line( 100,-100);
    check_line(-100,-100);
enddefine;


;;; To see most angles from small to big type: check_angles();
;;; (can be combined with check_orient)
define check_angle( n );
lvars n;
   draw_round_lines(50+n, 0+n, 0+n, 0+n, 0+2*n, 100+n, 20);
enddefine;

define check_angles();
lvars n;
    go_clear( go_default_pane );
    for n from -200 by 25 to 200 do
        check_angle( n );
    endfor;
enddefine;


;;; Check small to big go_radius with: check_radii();
;;; Note: the go_radius is limited to half the length of the lines
;;; (can be combined with check_orient)
define check_radius( n );
lvars n;
   draw_round_lines(100+n, 0+n, 0+n, 0+n, 0+n, 150+n, n);
enddefine;

define check_radii();
lvars n;
    go_clear( go_default_pane );
    for n from 0 by 5 to 60 do
        check_radius( n );
    endfor;
enddefine;


;;; Check a particular go_orientation of x and y directions with:
;;;                 check_orient( <go_xscale>, <go_yscale> );
;;; (Other tests can be used to see its influence on an go_orientation)
;;; The four main orientations can be viewed one after the other with:
;;;                 check_orients();
define check_orient(x, y);
lvars n, x, y;
    x -> go_default_pane.go_xscale; y -> go_default_pane.go_yscale;
    for n from 0 by 20 to 200 do check_angle( n ); endfor;
enddefine;

define check_orients();
lvars x, y;
    go_clear( go_default_pane );
    go_default_pane.go_xscale -> x;
    go_default_pane.go_yscale -> y;
    check_orient( 1, 1); syssleep( 200 );
    check_orient( 1,-1); syssleep( 200 );
    check_orient(-1, 1); syssleep( 200 );
    check_orient(-1,-1); syssleep( 200 );
    x -> go_default_pane.go_xscale;
    y -> go_default_pane.go_yscale;
enddefine;


/*
-- SETS OF MULTIPLE ROUNDED LINES ------------------------------------------
 */

;;; Routine that draws a set of multiple rounded lines
define :method draw_round_polylines(coords, npoints, closed, radius );
lvars coords, npoints, closed, radius;
lvars pane = go_default_pane, poly = instance go_polygon ;
                                         go_world_coords = coords;
                                         go_npoints      = npoints;
                                         go_closed       = closed;
                                         go_rounding     = radius;
                                     endinstance;
    go_add_to( poly, pane );
enddefine;


;;; check go_rounding on open or go_closed polylines (see TEACH * GO).
define check_polylines();
    go_init_rc();
    ;;; open
    draw_round_polylines([%100,10,-200,-200,200,0,100,-100%], 4, false, 20);
    ;;; go_closed
    draw_round_polylines([%0, 0, 100, 100, 200, 0, 200, 100%], 4, true, 20);
    draw_round_polylines([%5, 5,-100,-100,-200, 5,-200, 100%], 4, true, 40);
enddefine

/* end test programs  */

--- C.all/lib/proto/go/teach/go_roundlines
--- Copyright University of Sussex 1993. All rights reserved.
