coastwatch and skywatch could see too far
Both coas() and skyw() want to iterate over a circular area with radius vrange. They did that by iterating over a rectangle that encloses the circle, skipping coordinates out of range. To "save time", they used a rather odd predicate for "out of range", namely "vrange * vrange < (j * j + 3 * k * k) / 4)". The predicate is wrong. coastwatch and skywatch could see one sector too far in certain directions for practical radar ranges, and up to two sectors for not so practical tech 1900+ radar stations. For instance, with j = 13 and k = 3, vrange = 7, the predicate evaluates to false (49 < 48), i.e. in range. However, the true distance is 8, i.e. out of range. Likewise, j = 22, k = 8, vrange = 13: 169 < 169, true distance 15. Fix by iterating over the circle directly, without comparing distances.
This commit is contained in:
parent
38befcb446
commit
5e08b7fa55
2 changed files with 14 additions and 34 deletions
|
@ -59,10 +59,9 @@ coas(void)
|
||||||
struct nstr_sect nstr;
|
struct nstr_sect nstr;
|
||||||
struct coast *cp;
|
struct coast *cp;
|
||||||
struct coast *list[TSIZE];
|
struct coast *list[TSIZE];
|
||||||
int i, k, j, n;
|
int i, n;
|
||||||
int vrange, see;
|
int vrange, see;
|
||||||
int x, y;
|
int x, y, dx, dy, dxmax;
|
||||||
int mink, minj, maxk, maxj;
|
|
||||||
int nship = 0;
|
int nship = 0;
|
||||||
double tech;
|
double tech;
|
||||||
struct nstr_item ni;
|
struct nstr_item ni;
|
||||||
|
@ -104,20 +103,11 @@ coas(void)
|
||||||
vrange = (int)(sect.sct_effic / 100.0 * see * tech);
|
vrange = (int)(sect.sct_effic / 100.0 * see * tech);
|
||||||
if (vrange < 1)
|
if (vrange < 1)
|
||||||
vrange = 1;
|
vrange = 1;
|
||||||
maxk = vrange;
|
for (dy = -vrange; dy <= vrange; dy++) {
|
||||||
maxj = vrange * 2;
|
y = ynorm(sect.sct_y + dy);
|
||||||
vrange *= vrange;
|
dxmax = 2 * vrange - abs(dy);
|
||||||
mink = -maxk;
|
for (dx = -dxmax; dx <= dxmax; dx += 2) {
|
||||||
minj = -maxj;
|
x = xnorm(sect.sct_x + dx);
|
||||||
for (j = minj; j <= maxj && nship; j++) {
|
|
||||||
x = xnorm(sect.sct_x + j);
|
|
||||||
for (k = mink; k <= maxk && nship; k++) {
|
|
||||||
if ((j + k) & 01)
|
|
||||||
continue;
|
|
||||||
/* quick range check to save time... */
|
|
||||||
if (vrange < (j * j + 3 * k * k) / 4)
|
|
||||||
continue;
|
|
||||||
y = ynorm(sect.sct_y + k);
|
|
||||||
n = scthash(x, y, TSIZE);
|
n = scthash(x, y, TSIZE);
|
||||||
if (!list[n])
|
if (!list[n])
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -57,10 +57,9 @@ skyw(void)
|
||||||
struct nstr_sect nstr;
|
struct nstr_sect nstr;
|
||||||
struct sky *skyp;
|
struct sky *skyp;
|
||||||
struct sky *list[TSIZE];
|
struct sky *list[TSIZE];
|
||||||
int i, k, j, n;
|
int i, n;
|
||||||
int vrange, see;
|
int vrange, see;
|
||||||
int x, y;
|
int x, y, dx, dy, dxmax;
|
||||||
int mink, minj, maxk, maxj;
|
|
||||||
int nsat = 0;
|
int nsat = 0;
|
||||||
double tech;
|
double tech;
|
||||||
struct nstr_item ni;
|
struct nstr_item ni;
|
||||||
|
@ -96,20 +95,11 @@ skyw(void)
|
||||||
vrange = (int)(sect.sct_effic / 100.0 * see * tech);
|
vrange = (int)(sect.sct_effic / 100.0 * see * tech);
|
||||||
if (vrange < 1)
|
if (vrange < 1)
|
||||||
vrange = 1;
|
vrange = 1;
|
||||||
maxk = vrange;
|
for (dy = -vrange; dy <= vrange; dy++) {
|
||||||
maxj = vrange * 2;
|
y = ynorm(sect.sct_y + dy);
|
||||||
vrange *= vrange;
|
dxmax = 2 * vrange - abs(dy);
|
||||||
mink = -maxk;
|
for (dx = -dxmax; dx <= dxmax; dx += 2) {
|
||||||
minj = -maxj;
|
x = xnorm(sect.sct_x + dx);
|
||||||
for (j = minj; j <= maxj && nsat; j++) {
|
|
||||||
x = xnorm(sect.sct_x + j);
|
|
||||||
for (k = mink; k <= maxk && nsat; k++) {
|
|
||||||
if ((j + k) & 01)
|
|
||||||
continue;
|
|
||||||
/* quick range check to save time... */
|
|
||||||
if (vrange < (j * j + 3 * k * k) / 4)
|
|
||||||
continue;
|
|
||||||
y = ynorm(sect.sct_y + k);
|
|
||||||
n = scthash(x, y, TSIZE);
|
n = scthash(x, y, TSIZE);
|
||||||
if (!list[n])
|
if (!list[n])
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue