From: ian Date: Sun, 1 Feb 2004 17:53:47 +0000 (+0000) Subject: variable swept area X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=4ca185debfb17913dc8fa85083a56c7376c5641c;p=trains.git variable swept area --- diff --git a/layout/layout b/layout/layout index 53b6ec1..041bfc4 100755 --- a/layout/layout +++ b/layout/layout @@ -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/) {