X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=blobdiff_plain;f=layout%2Flayout;fp=layout%2Flayout;h=f6d9cc0beb6d4406598ee18d95d599fec9b86a61;hb=703c4e43451ba8638f167b8c8c08c30cca73fa64;hp=87d5c66c33aed1f488b80056642c4a9c97cf611b;hpb=b15619f68900e8f87b48c361ec1eb31a9713ec30;p=trains.git diff --git a/layout/layout b/layout/layout index 87d5c66..f6d9cc0 100755 --- a/layout/layout +++ b/layout/layout @@ -253,16 +253,18 @@ our $allwidthmin= allwidth(undef); # $seggraphends{"$bareseg"}[]{X} # $seggraphends{"$bareseg"}[]{Y} # $seggraphends{"$bareseg"}[]{A} -# $seggraphends{"-$bareseg"}[]... -# $seggraphend[0]{X} -# $seggraphend[0]{Y} -# $seggraphend[1]{X} -# $seggraphend[1]{Y} +# $seggraphaim->{X} +# $seggraphaim->{Y} +# $seggraphbest{$bareseg}{X} +# $seggraphbest{$bareseg}{Y} +# $seggraphbest{$bareseg}{A} +# $seggraphbest{$bareseg}{D2} our $ctx; our %objs; our %seggraphends; -our @seggraphend; +our $seggraphaim; +our %seggraphbest; our @al; # current cmd our $o=''; @@ -395,12 +397,23 @@ sub v_subtract ($$) { return { X => $b->{X} - $a->{X}, Y => $b->{Y} - $a->{Y} }; } -sub v_len ($) { +sub v_lensquared ($) { # v_len(V) # scalar length of V my ($v)=@_; my ($x,$y) = ($v->{X}, $v->{Y}); - return sqrt($x*$x + $y*$y); + return $x*$x + $y*$y; +} +sub v_len ($) { + # v_len(V) + # scalar length of V + my ($v)=@_; + return sqrt(v_lensquared($v)); +} +sub v_distsquared ($$) { + # v_dist(A,B) + # returns squared distance from A to B + return v_lensquared(v_subtract($_[0],$_[1])); } sub v_dist ($$) { # v_dist(A,B) @@ -718,19 +731,13 @@ sub segment_state_restore ($) { } sub segment__check_graphends () { - my ($bare,$ge,$i,$key); - @seggraphend= (); + my ($bare,$ge,$i,$key,@end); + $seggraphaim= undef; $segments[0] =~ m/^\-?(\w+)/ or return; $bare= $1; - foreach $i (qw(0 1)) { - $key= ('', '-')[$i].$bare; - $ge= $seggraphends{$key}; - defined $ge or return; -#print STDERR "$key @$ge\n"; -#map { print STDERR " ".join('|',keys %{$_}),"<\n"; } @$ge; - $seggraphend[$i]= v_mean(@$ge); -#print STDERR "SGE $i $seggraphend[$i]{X} $seggraphend[$i]{Y}\n"; - } + $ge= $seggraphends{$bare}; + defined $ge or return; + $seggraphaim= v_mean(@$ge); } sub segment_used_begin ($) { @@ -768,7 +775,7 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n"; $draw= current_draw(); if ($draw =~ m/[QGE]/) { my ($pt,$going,$red,$csegbare,$movfeat,$movstroke); - my ($used_last,$me,$segsave,$diff); + my ($used_last,$me,$segsave,$diff, $best,$dist2,$segvbare,$segvbaren); o("gsave\n"); $segsave= segment_state_save(); foreach $me ($draw =~ m/Q/ ? qw(q) : qw(e m)) { @@ -825,15 +832,18 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n"; $param += $ppu; last if $param>=$p1; $pt= &$calcfn; - if ($draw =~ m/E/ && @seggraphend==2) { - $diff= v_len(v_subtract($pt, $seggraphend[0])) - - v_len(v_subtract($pt, $seggraphend[1])); - if (abs($diff) < $psu_ulen*3) { - $segments[0] =~ m/^(\-?)(\w+)/; - $seglabel{$2}{X}= $pt->{X}; - $seglabel{$2}{Y}= $pt->{Y}; - $seglabel{$2}{A}= $pt->{A}; - $seglabel{$2}{A} += $pi if length($1); + if ($draw =~ m/E/ && $seggraphaim) { + $segments[0] =~ m/^(\-?)(\w+)/ or die; + ($segvbaren,$segvbare)=($1,$2); + $dist2= v_distsquared($pt, $seggraphaim); + $best= $seggraphbest{$segvbare}; + if (!$best or $dist2 < $best->{D2}) { + $best= { X => $pt->{X}, + Y => $pt->{Y}, + A => $pt->{A}, + D2 => $dist2 }; + $best->{A} += $pi if length($segvbaren); + $seggraphbest{$segvbare}= $best; } } segment_used_middle($psu_ulen,$pt); @@ -862,20 +872,6 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n"; parametric__o_pt(&$calcfn); o(" stroke\n"); } - if ($draw =~ m/E/) { - my ($pt,$seg); - foreach $seg (keys %seglabel) { - $pt= $seglabel{$seg}; - ol(" gsave\n"); - o_transform($pt); - ol(" /s ($seg) def\n". - " sf setfont\n". - " 0 0 moveto\n". - " s stringwidth pop -0.5 mul $lmu_segtxtoff moveto\n". - " s show\n". - " grestore\n"); - } - } if ($draw =~ m/[ARS]/) { for ($pa= $p0; $pa<$p1; $pa=$pb) { $pb= $pa + $ppu; $param= $pa; $ends[0]= @ends ? $ends[1] : &$calcfn; @@ -1431,7 +1427,7 @@ sub cmd_segcmap { sub cmd_segend { my ($from,$sp) = @_; $from= can(\&cva_idex); - $sp= can(\&cva_segment_n); + $sp= can(\&cva_segment); #print STDERR "setting $from ".join('|',keys %$from),"<\n"; push @{ $seggraphends{$sp} }, $from; }; @@ -1761,6 +1757,21 @@ while (<>) { cmd__one(); } +{ + my ($seg, $pt); + foreach $seg (keys %seggraphbest) { + $pt= $seggraphbest{$seg}; + ol(" gsave\n"); + o_transform($pt); + ol(" /s ($seg >) def\n". + " sf setfont\n". + " 0 0 moveto\n". + " s stringwidth pop -0.5 mul $lmu_segtxtoff moveto\n". + " s show\n". + " grestore\n"); + } +} + { my ($min_x, $max_x, $min_y, $max_y) = bbox($ctx->{Loc}); my ($bboxstr);