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;
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
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);
}
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);
$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/) {
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);
}
$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),
$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 {
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/) {