|
82 | 82 | <input type="radio" name="algorithm" value="spectrum">
|
83 | 83 | Noam's old/new spectrum
|
84 | 84 | </label>
|
| 85 | + <label> |
| 86 | + <input type="radio" name="algorithm" value="spectrum2"> |
| 87 | + Noam's old/new spectrum, preserving circular corners |
| 88 | + </label> |
85 | 89 | </form>
|
86 | 90 | <output id="output"></output>
|
87 | 91 | <script>
|
|
329 | 333 | }
|
330 | 334 | }
|
331 | 335 | else if (algorithm === "spectrum") {
|
332 |
| - const old_spec = (value) => { |
333 |
| - if (value == 0) |
334 |
| - return 0; |
335 |
| - return value + testCase.spread; |
336 |
| - } |
337 |
| - |
338 |
| - const new_spec = (value) => { |
339 |
| - if (value >= testCase.spread) { |
340 |
| - return value + testCase.spread; |
341 |
| - } |
342 |
| - let r = value / testCase.spread; |
343 |
| - return value + testCase.spread * (1 + (r - 1)**3); |
344 |
| - } |
345 |
| - |
346 | 336 | const map_dim = (radius, dim) => {
|
347 | 337 | // If there's no radius, there's no spread to apply.
|
348 | 338 | if (radius === 0) {
|
|
380 | 370 | bottomLeft: map(radii.bottomLeft)
|
381 | 371 | };
|
382 | 372 | }
|
| 373 | + else if (algorithm === "spectrum2") { |
| 374 | + const axial_spread_factor = (radius, dim) => { |
| 375 | + // If there's no radius, there's no spread to apply. |
| 376 | + if (radius === 0) { |
| 377 | + return 0; |
| 378 | + } |
| 379 | + |
| 380 | + // Calculate the radius's ratio to the spread, clamping at 1. |
| 381 | + const spreadRatio = 1 - Math.min(1, radius / testCase.spread); |
| 382 | + |
| 383 | + // Calculate the diameter's ratio to the overall dimension, clamping at 1. |
| 384 | + const dimRatio = Math.min(1, (2 * radius) / dim); |
| 385 | + |
| 386 | + // These factors determine the amount of easing. They both approach 0 |
| 387 | + // as their respective ratios approach 1, which reduces the easing effect. |
| 388 | + const spreadEasingFactor = spreadRatio ** 3; |
| 389 | + const dimEasingFactor = 1 - dimRatio ** 3; |
| 390 | + |
| 391 | + // The total reduction in spread is the product of the two easing factors. |
| 392 | + const totalReduction = dimEasingFactor * spreadEasingFactor; |
| 393 | + return 1 - totalReduction; |
| 394 | + } |
| 395 | + |
| 396 | + for (let corner in radii) { |
| 397 | + let spread_factor = Math.min( |
| 398 | + axial_spread_factor(radii[corner][0], testCase.width), |
| 399 | + axial_spread_factor(radii[corner][1], testCase.height), |
| 400 | + ); |
| 401 | + r[corner] = radii[corner].map(radius => { |
| 402 | + return radius + testCase.spread * spread_factor; |
| 403 | + }); |
| 404 | + } |
| 405 | + } |
383 | 406 |
|
384 | 407 | return `${r.topLeft[0]}px ${r.topRight[0]}px ${r.bottomRight[0]}px ${r.bottomLeft[0]}px / ${r.topLeft[1]}px ${r.topRight[1]}px ${r.bottomRight[1]}px ${r.bottomLeft[1]}px`;
|
385 | 408 | }
|
|
0 commit comments