# $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='';
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)
}
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 ($) {
$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)) {
$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);
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;
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;
};
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);