|
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