[instancer.solver] Fix up algorithm again

This commit is contained in:
Behdad Esfahbod 2022-08-08 08:33:32 -06:00
parent 6210e7d331
commit 8a49fdc4ec
2 changed files with 35 additions and 9 deletions

View File

@ -49,20 +49,36 @@ def _solveWithGain(tent, axisLimit):
gain = supportScalar({'tag': axisDef}, {'tag': tent}) gain = supportScalar({'tag': axisDef}, {'tag': tent})
out = [(gain, axisLimit)] out = [(gain, axisLimit)]
# First, the positive side # First, the positive side
# case 3a: gain is more than outGain.
outGain = supportScalar({'tag': axisMax}, {'tag': tent})
if gain > outGain:
crossing = peak + ((1 - gain) * (upper - peak) / (1 - outGain))
loc1 = (peak, peak, crossing)
scalar1 = 1
loc2 = (crossing, axisMax, axisMax)
scalar2 = 0
out.append((scalar1 - gain, loc1))
if (peak < upper):
out.append((scalar2 - gain, loc2))
# case 3: outermost limit still fits within F2Dot14 bounds; # case 3: outermost limit still fits within F2Dot14 bounds;
# we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0 # we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0
# or +1.0 will never be applied as implementations must clamp to that range. # or +1.0 will never be applied as implementations must clamp to that range.
if axisDef + (axisMax - axisDef) * 2 >= upper: elif axisDef + (axisMax - axisDef) * 2 >= upper:
if axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper: if axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper:
# we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience # we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14 upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14
if upper > axisDef: if upper > axisDef:
out.append((0 - gain, (axisDef, peak, upper))) out.append((1 - gain, (axisDef, peak, upper)))
# case 4: new limit doesn't fit; we need to chop the deltaset into two 'tents', # case 4: new limit doesn't fit; we need to chop the deltaset into two 'tents',
# because the shape of a triangle with part of one side cut off cannot be # because the shape of a triangle with part of one side cut off cannot be
@ -71,7 +87,7 @@ def _solveWithGain(tent, axisLimit):
else: else:
loc1 = (axisDef, peak, axisMax) loc1 = (axisDef, peak, axisMax)
scalar1 = 0 scalar1 = 1
loc2 = (peak, axisMax, axisMax) loc2 = (peak, axisMax, axisMax)
scalar2 = supportScalar({'tag': axisMax}, {'tag': tent}) scalar2 = supportScalar({'tag': axisMax}, {'tag': tent})

View File

@ -84,12 +84,22 @@ class RebaseTentTest(object):
# With gain: # With gain:
# #
# Case 1neg # Case 3/1neg
pytest.param( pytest.param(
(.0, .5, 1), (0, .5, 1), (.0, .5, 1), (0, .5, 1),
[ [
(1, (-1, 0, 1)), (1, (-1, 0, 1)),
(-1, (0, 0, 1)), (-1, (0, 1, 1)),
(-1, (-1, -1, 0)),
]
),
# Case 4/1neg
pytest.param(
(.0, .5, 2), (0, .5, .8),
[
(1, (-1, 0, 1)),
(-1.0, (0.0, 1, 1)),
(-1, (-1, -1, 0)), (-1, (-1, -1, 0)),
] ]
), ),
@ -99,7 +109,7 @@ class RebaseTentTest(object):
(.0, .5, 1), (0, .25, .5), (.0, .5, 1), (0, .25, .5),
[ [
(.5, (-1, 0, 1)), (.5, (-1, 0, 1)),
(-.5, (0, 1, 1)), (.5, (0, 1, 1)),
(-.5, (-1, -1, 0)), (-.5, (-1, -1, 0)),
] ]
), ),
@ -109,7 +119,7 @@ class RebaseTentTest(object):
(.05, .55, 1), (0, .25, .5), (.05, .55, 1), (0, .25, .5),
[ [
(.4, (-1.0, 0.0, 1.0)), (.4, (-1.0, 0.0, 1.0)),
(-.4, (0.0, 1.0, 1.0)), (.5, (0, 1, 1)),
(-.4, (-1, -.8, 0)), (-.4, (-1, -.8, 0)),
(-.4, (-1, -1, -.8)), (-.4, (-1, -1, -.8)),
] ]
@ -120,4 +130,4 @@ class RebaseTentTest(object):
sol = solver.rebaseTent(tent, axisRange) sol = solver.rebaseTent(tent, axisRange)
assert sol == expected assert sol == expected, (tent, axisRange)