chiark / gitweb /
variable swept area
authorian <ian>
Sun, 1 Feb 2004 17:53:47 +0000 (17:53 +0000)
committerian <ian>
Sun, 1 Feb 2004 17:53:47 +0000 (17:53 +0000)
layout/layout

index 53b6ec1a30c824b14888a2d7129a6fd5c3154b0a..041bfc41c38f958838d3387f2558349a970f1425 100755 (executable)
@@ -12,7 +12,6 @@ our $psu_edgelw= 0.5;
 our $psu_ticklw= 0.1;
 our $psu_ticksperu= 1;
 our $psu_ticklen= 5.0;
-our $psu_allwidth= 37.0/2;
 our $psu_gauge= 9;
 our $psu_sleeperlen= 17;
 our $psu_sleeperlw= 15;
@@ -38,8 +37,18 @@ our $olu_textallowperc= $lmu_marktpt * 5.0/11;
 
 our $pi= atan2(0,-1);
 
-our $draw_t_def= '1';
-$draw_t_def= 'T';
+sub allwidth2 ($) {
+    my ($radius)= @_;
+    return 27 unless defined $radius;
+    $radius= abs($radius);
+    return ($radius >= 450 ? 33 :
+           $radius >= 400 ? 35 :
+           37);
+}
+sub allwidth ($) { return allwidth2($_[0]) * 0.5; }
+
+our $allwidthmax= allwidth(0);
+our $allwidthmin= allwidth(undef);
 
 # Data structures:
 #  $ctx->{CmdLog}= undef                  } not in defobj
@@ -180,10 +189,10 @@ sub bbox ($) {
     my ($min_x, $max_x, $min_y, $max_y);
     my ($loc);
     foreach $loc (values %$objhash) {
-       upd_min(\$min_x, $loc->{X} - abs($psu_allwidth * sin($loc->{A})));
-       upd_max(\$max_x, $loc->{X} + abs($psu_allwidth * sin($loc->{A})));
-       upd_min(\$min_y, $loc->{Y} - abs($psu_allwidth * cos($loc->{A})));
-       upd_max(\$max_y, $loc->{Y} + abs($psu_allwidth * cos($loc->{A})));
+       upd_min(\$min_x, $loc->{X} - abs($allwidthmax * sin($loc->{A})));
+       upd_max(\$max_x, $loc->{X} + abs($allwidthmax * sin($loc->{A})));
+       upd_min(\$min_y, $loc->{Y} - abs($allwidthmax * cos($loc->{A})));
+       upd_max(\$max_y, $loc->{Y} + abs($allwidthmax * cos($loc->{A})));
     }
     return ($min_x, $max_x, $min_y, $max_y);
 }
@@ -391,18 +400,19 @@ sub parametric__o_pt ($) {
     o_path_point("$pt->{X} $pt->{Y}");
 }
 
-sub parametric_segment ($$$$) {
-    my ($p0,$p1,$lenperp,$calcfn) = @_;
+sub parametric_segment ($$$$$) {
+    my ($p0,$p1,$lenperp,$minradius,$calcfn) = @_;
     # makes $p (global) go from $p0 to $p1  ($p1>$p0)
     # $lenperp is the length of one unit p, ie the curve
     # must have a uniform `density' in parameter space
     # $calcfn is invoked with $p set and should return a loc
     # (ie, ref to X =>, Y =>, A =>).
-    my ($pa,$pb,@ends,$side,$ppu,$e,$v,$tick,$draw);
+    my ($pa,$pb,@ends,$side,$ppu,$e,$v,$tick,$draw,$allwidth);
     return unless $ctx->{Draw} =~ m/[ARSC]/;
     $ppu= $psu_ulen/$lenperp;
+    $allwidth= allwidth($minradius);
     my ($railctr)=($psu_gauge + $psu_raillw)*0.5;
-    my ($tickend)=($psu_allwidth - $psu_ticklen);
+    my ($tickend)=($allwidth - $psu_ticklen);
     my ($tickpitch)=($psu_ulen / $psu_ticksperu);
     my ($sleeperctr)=($psu_ulen*0.5);
     my ($sleeperend)=($psu_sleeperlen*0.5);
@@ -429,10 +439,10 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
        $e= $pb<=$p1 ? 1.0 : ($p1-$pa)/$ppu;
        o("    gsave\n");
        o_path_begin();
-       o_path_point(psu_coords(\@ends,0,-$psu_allwidth));
-       o_path_point(psu_coords(\@ends,0,$psu_allwidth));
-       o_path_point(psu_coords(\@ends,$e,$psu_allwidth));
-       o_path_point(psu_coords(\@ends,$e,-$psu_allwidth));
+       o_path_point(psu_coords(\@ends,0,-$allwidth));
+       o_path_point(psu_coords(\@ends,0,$allwidth));
+       o_path_point(psu_coords(\@ends,$e,$allwidth));
+       o_path_point(psu_coords(\@ends,$e,-$allwidth));
        o("        closepath clip\n");
        foreach $side qw(-1 1) {
            if ($draw =~ m/R/) {
@@ -449,11 +459,11 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
        if ($draw =~ m/A/) {
            o("        0.5 setgray\n");
            foreach $side qw(-1 1) {
-               o_line(psu_coords(\@ends,0,$side*$psu_allwidth),
-                      psu_coords(\@ends,1.5,$side*$psu_allwidth),
+               o_line(psu_coords(\@ends,0,$side*$allwidth),
+                      psu_coords(\@ends,1.5,$side*$allwidth),
                       $psu_edgelw);
                for ($tick=0; $tick<1.5; $tick+=$tickpitch/$psu_ulen) {
-                   o_line(psu_coords(\@ends,$tick,$side*$psu_allwidth),
+                   o_line(psu_coords(\@ends,$tick,$side*$allwidth),
                           psu_coords(\@ends,$tick,$side*$tickend),
                           $psu_ticklw);
                }
@@ -475,7 +485,7 @@ sub arc ($$$$$) {
     $to->{X}= $ctr->{X} - $radius * sin($beta);
     $to->{Y}= $ctr->{Y} + $radius * cos($beta);
     return if abs($delta*$radius) < 1E-9;
-    parametric_segment(0.0,1.0, abs($radius*$delta), sub {
+    parametric_segment(0.0,1.0, abs($radius*$delta), $radius, sub {
        my ($beta) = $from->{A} + $delta * $param;
        return { X => $ctr->{X} - $radius * sin($beta),
                 Y => $ctr->{Y} + $radius * cos($beta),
@@ -603,7 +613,7 @@ sub cmd_extend {
        $to->{X}= $from->{X} + $len * cos($from->{A});
        $to->{Y}= $from->{Y} + $len * sin($from->{A});
        $to->{A}= $from->{A};
-       parametric_segment(0.0, 1.0, abs($len), sub {
+       parametric_segment(0.0, 1.0, abs($len), undef, sub {
            ev_lincomb({}, $from, $to, $param);
        });
     } else {
@@ -826,8 +836,8 @@ dv("cmd__do $ctx @al ",'$ctx',$ctx);
            ol("    gsave\n".
               "      $loc->{X} $loc->{Y} translate $ad rotate\n");
            if ($ctx->{Draw} =~ m/M/) {
-               ol("      0 $psu_allwidth newpath moveto\n".
-                  "      0 -$psu_allwidth lineto\n".
+               ol("      0 $allwidthmin newpath moveto\n".
+                  "      0 -$allwidthmin lineto\n".
                   "      $lmu_marklw setlinewidth stroke\n");
            }
            if ($ctx->{Draw} =~ m/L/) {