|
78 | 78 | <input type="radio" name="algorithm" value="oriol2">
|
79 | 79 | Oriol's variant of current spec (adding a linear factor)
|
80 | 80 | </label>
|
| 81 | + <label> |
| 82 | + <input type="radio" name="algorithm" value="spectrum"> |
| 83 | + Noam's old/new spectrum |
| 84 | + </label> |
81 | 85 | </form>
|
82 | 86 | <output id="output"></output>
|
83 | 87 | <script>
|
|
101 | 105 | {width: 200, height: 40, spread: 50, borderRadius: "0 50% / 50%"},
|
102 | 106 | {width: 0, height: 0, spread: 30, borderRadius: "50px 0px 0px 0px"},
|
103 | 107 | {width: 500, height: 500, spread: 30, borderRadius: "50px"},
|
| 108 | + {width: 250, height: 30, spread: 100, borderRadius: "10px"}, |
104 | 109 | ];
|
105 | 110 |
|
106 | 111 | function show({incremental = false} = {}) {
|
|
295 | 300 | }
|
296 | 301 | else if (algorithm === "oriol") {
|
297 | 302 | for (let corner in radii) {
|
298 |
| - let coverage = Math.max( |
| 303 | + let coverage = Math.min( |
299 | 304 | 2 * radii[corner][0] / testCase.width,
|
300 | 305 | 2 * radii[corner][1] / testCase.height,
|
301 | 306 | ) || 0;
|
|
310 | 315 | }
|
311 | 316 | else if (algorithm === "oriol2") {
|
312 | 317 | for (let corner in radii) {
|
313 |
| - let coverage = Math.max( |
| 318 | + let coverage = Math.min( |
314 | 319 | 2 * radii[corner][0] / testCase.width,
|
315 | 320 | 2 * radii[corner][1] / testCase.height,
|
316 | 321 | ) || 0;
|
|
323 | 328 | });
|
324 | 329 | }
|
325 | 330 | }
|
| 331 | + 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 | + const map_dim = (radius, dim) => { |
| 347 | + // If there's no radius, there's no spread to apply. |
| 348 | + if (radius === 0) { |
| 349 | + return 0; |
| 350 | + } |
| 351 | + |
| 352 | + // Calculate the radius's ratio to the spread, clamping at 1. |
| 353 | + const spreadRatio = 1 - Math.min(1, radius / testCase.spread); |
| 354 | + |
| 355 | + // Calculate the diameter's ratio to the overall dimension, clamping at 1. |
| 356 | + const dimRatio = Math.min(1, (2 * radius) / dim); |
| 357 | + |
| 358 | + // These factors determine the amount of easing. They both approach 0 |
| 359 | + // as their respective ratios approach 1, which reduces the easing effect. |
| 360 | + const spreadEasingFactor = spreadRatio ** 3; |
| 361 | + const dimEasingFactor = 1 - dimRatio ** 3; |
| 362 | + |
| 363 | + // The total reduction in spread is the product of the two easing factors. |
| 364 | + const totalReduction = dimEasingFactor * spreadEasingFactor; |
| 365 | + |
| 366 | + // Apply the reduction to the spread and add it to the original radius. |
| 367 | + const easedSpread = testCase.spread * (1 - totalReduction); |
| 368 | + |
| 369 | + return radius + easedSpread; |
| 370 | + } |
| 371 | + |
| 372 | + const map = ([h, v]) => { |
| 373 | + return [map_dim(h, testCase.width), map_dim(v, testCase.height)]; |
| 374 | + } |
| 375 | + |
| 376 | + r = { |
| 377 | + topLeft: map(radii.topLeft), |
| 378 | + topRight: map(radii.topRight), |
| 379 | + bottomRight: map(radii.bottomRight), |
| 380 | + bottomLeft: map(radii.bottomLeft) |
| 381 | + }; |
| 382 | + } |
326 | 383 |
|
327 | 384 | 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`;
|
328 | 385 | }
|
|
0 commit comments