diff --git a/src/App.vue b/src/App.vue
index e2b8b05..95b58bf 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -451,11 +451,11 @@
- r = (a2 - a1 - 1) / 2
+ r = -1 - a1
{{ formatFineCoeff(currentR) }}
- δ = (a1 + a2 + 1) / 2
+ δ = a1 + a2 + 1
{{ formatFineCoeff(currentDelta) }}
@@ -463,7 +463,7 @@
運算說明:
- δ = (a1 + a2 + 1) / 2,r = (a2 - a1 - 1) / 2。更改數值會自動更新圖表;桌機可用 ± 或 shift + 滾輪,觸控時按住數值面板上下拖曳。
+ a1 = -1 - r, a2 = r + δ。更改數值會自動更新圖表;桌機可用 ± 或 shift + 滾輪,觸控時按住數值面板上下拖曳。
@@ -605,21 +605,21 @@
{{ formatFixedFineCoeff(fixedCurrentDelta) }}
-
+
r
+ class="stepper-button w-full h-[42px] flex items-center justify-center rounded-full role-bg-primary-soft role-hover-primary-soft role-text-primary transition-all duration-150 active:scale-90 text-lg font-bold shadow-sm">-
+ class="min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center text-slate-700 dark:text-gray-300">
+ class="stepper-button w-full h-[42px] flex items-center justify-center rounded-full role-bg-primary-soft role-hover-primary-soft role-text-primary transition-all duration-150 active:scale-90 text-lg font-bold shadow-sm">+
@@ -627,18 +627,18 @@
- r = (a2 - a1 - a0) / 2
+ r = -a0 - a1
{{ formatFixedFineCoeff(fixedCurrentR) }}
- δ = (a1 + a2 + a0) / 2
+ δ = a1 + a2 + a0
{{ formatFixedFineCoeff(fixedCurrentDelta) }}
運算說明:
- a0 = 2^{{ shiftBitsA }},δ = (a1 + a2 + a0) / 2,r = (a2 - a1 - a0) / 2。
+ a0 = 2^{{ shiftBitsA }},a1 = -a0 - r, a2 = r + δ。
diff --git a/src/app-options.js b/src/app-options.js
index 4c48092..88821a1 100755
--- a/src/app-options.js
+++ b/src/app-options.js
@@ -58,7 +58,7 @@ export default {
shiftBitRepeatDelayTimer: null,
shiftBitRepeatTimer: null,
shiftBitDrag: null,
- fixedAFineStep: 0.5,
+ fixedAFineStep: 1,
fixedAFineDrag: null,
fixedAFineRepeatDelayTimer: null,
fixedAFineRepeatTimer: null,
@@ -171,10 +171,13 @@ export default {
return a[2] || 0;
},
currentDelta() {
- return (this.currentA1 + this.currentA2 + 1) / 2;
+ // New Model: a1 = -1 - r, a2 = r + delta
+ // => delta = a1 + a2 + 1
+ return this.currentA1 + this.currentA2 + 1;
},
currentR() {
- return (this.currentA2 - this.currentA1 - 1) / 2;
+ // New Model: a1 = -1 - r => r = -1 - a1
+ return -1 - this.currentA1;
},
currentA1A2Diff() {
return this.currentA1 - this.currentA2;
@@ -192,10 +195,13 @@ export default {
return this.fixedPointCoeffs.a[2]?.val || 0;
},
fixedCurrentDelta() {
- return (this.fixedCurrentA1 + this.fixedCurrentA2 + this.fixedA0Int) / 2;
+ // New Model: a1 = -a0 - r, a2 = r + delta
+ // => delta = a1 + a2 + a0
+ return this.fixedCurrentA1 + this.fixedCurrentA2 + this.fixedA0Int;
},
fixedCurrentR() {
- return (this.fixedCurrentA2 - this.fixedCurrentA1 - this.fixedA0Int) / 2;
+ // New Model: a1 = -a0 - r => r = -a0 - a1
+ return -this.fixedA0Int - this.fixedCurrentA1;
},
fixedCurrentA1A2Diff() {
return this.fixedCurrentA1 - this.fixedCurrentA2;
@@ -337,7 +343,7 @@ export default {
this.aFineStep = Number(clampedStep.toPrecision(12));
},
adjustFixedAFineStep(direction) {
- const steps = [0.5, 1, 2, 4, 8, 32, 256, 1024, 4096, 16384, 65536];
+ const steps = [1, 2, 4, 8, 32, 256, 1024, 4096, 16384, 65536];
let currentIdx = steps.indexOf(this.fixedAFineStep);
// 如果當前值不在數列中,找最接近的一個
@@ -358,7 +364,8 @@ export default {
const nextDelta = Number(delta);
const nextR = Number(r);
if (!Number.isFinite(nextDelta) || !Number.isFinite(nextR)) return;
- this.setA1A2(-1 - nextR + nextDelta, nextR + nextDelta);
+ // New Model: a1 = -1 - r, a2 = r + delta
+ this.setA1A2(-1 - nextR, nextR + nextDelta);
},
setAFineDirect(target, rawValue) {
const nextValue = parseFloat(rawValue);
@@ -413,20 +420,14 @@ export default {
window.removeEventListener('pointercancel', this.stopAFineDrag);
},
setFixedDeltaR(delta, r) {
- // 使用「兩倍值」空間進行整數運算
- let S = Math.round(delta * 2);
- let D = Math.round(r * 2);
+ const nextDelta = Math.round(delta);
+ const nextR = Math.round(r);
const a0 = this.fixedA0Int;
- // 核心邏輯:a1, a2 為整數的充要條件是 S 與 D 的奇偶性相同
- // 這裡採用「優先滿足目標值」的策略:如果奇偶不同,則微調其中一個
- // 由於此函數由 UI 直接調用,我們無法判斷使用者剛才改了誰
- // 所以我們預設採用 Math.round 來尋找最接近的整數組合
- const a2 = Math.round((S + D) / 2);
- const a1 = a2 - D - a0;
-
- this.fixedOverrides.a[1] = a1;
- this.fixedOverrides.a[2] = a2;
+ // New Model: a1 = -a0 - r, a2 = r + delta
+ // If r and delta are integers, a1 and a2 are guaranteed to be integers.
+ this.fixedOverrides.a[1] = -a0 - nextR;
+ this.fixedOverrides.a[2] = nextR + nextDelta;
this.debouncedUpdateBode();
},
setFixedAFineDirect(target, rawValue) {
@@ -439,40 +440,12 @@ export default {
}
},
adjustFixedAFineValue(target, steps) {
- let S = Math.round(this.fixedCurrentDelta * 2);
- let D = Math.round(this.fixedCurrentR * 2);
- const dVal = Math.round(steps * this.fixedAFineStep * 2);
- const a0 = this.fixedA0Int;
-
+ const dVal = Math.round(steps * this.fixedAFineStep);
if (target === 'delta') {
- // 優先保證 delta 變動到位
- S += dVal;
- // 檢查奇偶性是否匹配
- if ((S % 2 + 2) % 2 !== (D % 2 + 2) % 2) {
- // 核心:震盪平衡邏輯。
- // 如果 S 變為偶數,D 應該變為最近的偶數;如果 S 變為奇數,D 應該變為最近的奇數。
- // 我們判斷目前 D 是在 .5 還是 .0,然後向反方向跳轉,防止單向漂移。
- if (D % 2 !== 0) {
- D -= 1; // 10.5 -> 10.0
- } else {
- D += 1; // 10.0 -> 10.5
- }
- }
+ this.setFixedDeltaR(this.fixedCurrentDelta + dVal, this.fixedCurrentR);
} else if (target === 'r') {
- // 如果 r 沒被禁用,則優先保證 r 變動到位
- D += dVal;
- if ((S % 2 + 2) % 2 !== (D % 2 + 2) % 2) {
- if (S % 2 !== 0) S -= 1;
- else S += 1;
- }
+ this.setFixedDeltaR(this.fixedCurrentDelta, this.fixedCurrentR + dVal);
}
-
- const a2 = (S + D) / 2;
- const a1 = a2 - D - a0;
-
- this.fixedOverrides.a[1] = a1;
- this.fixedOverrides.a[2] = a2;
- this.debouncedUpdateBode();
},
handleFixedAFineWheel(target, event) {
if (!event.shiftKey) {