bug-groff
[Top][All Lists]

## [bug #65910] [pic] some dashed ellipse sizes produce irregular dashes

 From: G. Branden Robinson Subject: [bug #65910] [pic] some dashed ellipse sizes produce irregular dashes Date: Wed, 10 Jul 2024 17:26:53 -0400 (EDT)

```Follow-up Comment #8, bug #65910 (group groff):

Arc length, naïvely computed, would seem to be a poor metric.

The reason is floating-point division.  For some positions on the ellipse the
delta-x is very close to zero, so when you divide by the delta-x the number
blows up to hugeness.

If we just take the sums of the absolute values of delta-x and delta-y, we get
better behaved numbers that still communicate a sense of the "bigness" of
steps from vertex to vertex along the dashed ellipse.

diff --git a/src/preproc/pic/common.cpp b/src/preproc/pic/common.cpp
index 6a4a93eb9..32cfdfdae 100644
--- a/src/preproc/pic/common.cpp
+++ b/src/preproc/pic/common.cpp
@@ -1,4 +1,3 @@
-// -*- C++ -*-
/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)

@@ -172,8 +171,15 @@ void common_output::dashed_ellipse(const position &cent,
const distance &dim,
// and use it to get the exact value on the ellipse
double psi = atan2(zdot.y / dim_y, zdot.x / dim_x);
zdot = position(dim_x * cos(psi), dim_y * sin(psi));
-    if ((i % 2 == 0) && (i > 1))
+    if ((i % 2 == 0) && (i > 1)) {
+      fprintf(stderr, "abs-delta-y=%5.2f, abs-delta-x=%5.2f,"
+         " abssum=%5.2f, arclen=%5.2f\n",
+         fabs(zdot.y - zpre.y), fabs(zdot.x - zpre.x),
+         (fabs((zdot.y - zpre.y)) + fabs((zdot.x - zpre.x))),
+         (sqrt(fabs(zdot.y - zpre.y) / fabs(zdot.x - zpre.x))));
+      fflush(stderr);
ellipse_arc(cent, zpre, zdot, dim / 2, slt);
+    }
}
}

Let's look at the data for a good ellipse first, the 4x1.5 one.

\$ ./build/pic -t EXPERIMENTS/dashed-ellipse-4x1.5.ptex >|
EXPERIMENTS/dashed-ellipse-4x1.5.tex
abs-delta-y= 0.14, abs-delta-x= 0.21, abssum= 0.35, arclen= 0.83
abs-delta-y= 0.08, abs-delta-x= 0.24, abssum= 0.32, arclen= 0.58
abs-delta-y= 0.05, abs-delta-x= 0.25, abssum= 0.29, arclen= 0.44
abs-delta-y= 0.02, abs-delta-x= 0.26, abssum= 0.29, arclen= 0.29
abs-delta-y= 0.00, abs-delta-x= 0.25, abssum= 0.25, arclen= 0.02
abs-delta-y= 0.03, abs-delta-x= 0.29, abssum= 0.31, arclen= 0.30
abs-delta-y= 0.05, abs-delta-x= 0.25, abssum= 0.29, arclen= 0.44
abs-delta-y= 0.08, abs-delta-x= 0.24, abssum= 0.32, arclen= 0.59
abs-delta-y= 0.14, abs-delta-x= 0.21, abssum= 0.35, arclen= 0.84
abs-delta-y= 0.24, abs-delta-x= 0.00, abssum= 0.25, arclen= 8.35
abs-delta-y= 0.14, abs-delta-x= 0.21, abssum= 0.35, arclen= 0.83
abs-delta-y= 0.08, abs-delta-x= 0.24, abssum= 0.32, arclen= 0.58
abs-delta-y= 0.05, abs-delta-x= 0.25, abssum= 0.29, arclen= 0.44
abs-delta-y= 0.02, abs-delta-x= 0.26, abssum= 0.28, arclen= 0.29
abs-delta-y= 0.00, abs-delta-x= 0.25, abssum= 0.25, arclen= 0.04
abs-delta-y= 0.03, abs-delta-x= 0.28, abssum= 0.31, arclen= 0.30
abs-delta-y= 0.05, abs-delta-x= 0.25, abssum= 0.29, arclen= 0.44
abs-delta-y= 0.08, abs-delta-x= 0.24, abssum= 0.32, arclen= 0.59
abs-delta-y= 0.15, abs-delta-x= 0.20, abssum= 0.35, arclen= 0.84
abs-delta-y= 0.24, abs-delta-x= 0.01, abssum= 0.25, arclen= 5.82

We see that the sums of the (absolute) delta ys and delta xs consistently lie
within a range of 0.25 to 0.35 inches.  That's a bigger range than I was
expecting, if I'm honest, but since it's not a distance measure in the precise
sense, that could be okay.  I left the arc length in to show its poor utility
when one of the deltas is near zero.

Considering just the "abssum", we have what looks like a well behaved dashed
ellipse.

Now let's look at the problem child.

\$ ./build/pic -t EXPERIMENTS/dashed-ellipse-8x3.ptex >|
EXPERIMENTS/dashed-ellipse-8x3.tex
abs-delta-y= 0.19, abs-delta-x= 0.16, abssum= 0.35, arclen= 1.09
abs-delta-y= 0.17, abs-delta-x= 0.29, abssum= 0.46, arclen= 0.77
abs-delta-y= 0.11, abs-delta-x= 0.26, abssum= 0.37, arclen= 0.64
abs-delta-y= 0.08, abs-delta-x= 0.27, abssum= 0.35, arclen= 0.55
abs-delta-y= 0.07, abs-delta-x= 0.31, abssum= 0.38, arclen= 0.46
abs-delta-y= 0.06, abs-delta-x= 0.40, abssum= 0.45, arclen= 0.38
abs-delta-y= 0.04, abs-delta-x= 0.50, abssum= 0.55, arclen= 0.29
abs-delta-y= 0.02, abs-delta-x= 0.63, abssum= 0.64, arclen= 0.17
abs-delta-y= 0.00, abs-delta-x= 0.13, abssum= 0.13, arclen= 0.08
abs-delta-y= 0.00, abs-delta-x= 0.01, abssum= 0.01, arclen= 0.24
abs-delta-y= 0.00, abs-delta-x= 0.00, abssum= 0.00, arclen= -nan
abs-delta-y= 0.07, abs-delta-x= 0.42, abssum= 0.49, arclen= 0.41
abs-delta-y= 0.11, abs-delta-x= 0.46, abssum= 0.57, arclen= 0.49
abs-delta-y= 0.14, abs-delta-x= 0.45, abssum= 0.59, arclen= 0.57
abs-delta-y= 0.17, abs-delta-x= 0.37, abssum= 0.54, arclen= 0.67
abs-delta-y= 0.15, abs-delta-x= 0.24, abssum= 0.39, arclen= 0.80
abs-delta-y= 0.19, abs-delta-x= 0.16, abssum= 0.35, arclen= 1.10
abs-delta-y= 0.25, abs-delta-x= 0.00, abssum= 0.25, arclen= 7.82
abs-delta-y= 0.19, abs-delta-x= 0.16, abssum= 0.35, arclen= 1.08
abs-delta-y= 0.17, abs-delta-x= 0.28, abssum= 0.45, arclen= 0.77
abs-delta-y= 0.10, abs-delta-x= 0.25, abssum= 0.36, arclen= 0.64
abs-delta-y= 0.08, abs-delta-x= 0.26, abssum= 0.33, arclen= 0.54
abs-delta-y= 0.06, abs-delta-x= 0.30, abssum= 0.37, arclen= 0.46
abs-delta-y= 0.06, abs-delta-x= 0.39, abssum= 0.44, arclen= 0.38
abs-delta-y= 0.04, abs-delta-x= 0.50, abssum= 0.54, arclen= 0.29
abs-delta-y= 0.02, abs-delta-x= 0.62, abssum= 0.63, arclen= 0.17
abs-delta-y= 0.00, abs-delta-x= 0.14, abssum= 0.14, arclen= 0.08
abs-delta-y= 0.00, abs-delta-x= 0.02, abssum= 0.02, arclen= 0.25
abs-delta-y= 0.00, abs-delta-x= 0.00, abssum= 0.00, arclen= -nan
abs-delta-y= 0.07, abs-delta-x= 0.41, abssum= 0.48, arclen= 0.41
abs-delta-y= 0.11, abs-delta-x= 0.45, abssum= 0.56, arclen= 0.49
abs-delta-y= 0.14, abs-delta-x= 0.44, abssum= 0.58, arclen= 0.57
abs-delta-y= 0.16, abs-delta-x= 0.36, abssum= 0.53, arclen= 0.67
abs-delta-y= 0.15, abs-delta-x= 0.23, abssum= 0.38, arclen= 0.80
abs-delta-y= 0.19, abs-delta-x= 0.16, abssum= 0.35, arclen= 1.11
abs-delta-y= 0.25, abs-delta-x= 0.01, abssum= 0.25, arclen= 5.53

We have more arc segments (36 vs. 20), which makes intuitive sense since the
ellipse is bigger.  (I hesitate to offer a precise quantitative estimate of
how many more arc segments we should expect from a ellipse that doubles its
dimensions, because that quantity would seem to depend on the ellipse's
eccentricity.  For example, an extremely eccentric ellipse that is nearly two
line segments stacked on top of each other would simply double the number of
constituent arc segments of uniform length.  But an ellipse with an
eccentricity of zero is a circle, and by the familiar relation C=πd, if we
double its diameter, we get ~3.14 times the length around, and therefore 3.14
times as many arc segments of uniform length.  With these bounds, we should
expect the number of arc segments in the double-sized ellipse to lie between
20*2=40 and 20*3.14=63 (approx.) ...which 36 is not.  Here, perhaps, is one of
the indicators of trouble.)

A more obvious problem is that "abssum" is *all over the place*, dipping even
to zero.  That's just no good a 'tall.

So I guess the problem is with the transform from the affine circle.

I might need that heavier math after all.

_______________________________________________________

<https://savannah.gnu.org/bugs/?65910>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
```

signature.asc
Description: PGP signature