Matematiskt problem för litet program

Permalänk
Medlem

Matematiskt problem för litet program

Skulle uppskatta lite matematisk hjälp med ett mindre program jag gör, i en C-liknande kod som kallas EEL. Min matte verkar inte räcka till för det jag behöver lösa.

Jag har två variabler, kallar dom A och B.

Värdet A är ett siffervärde, som kommer från ett GUI skjutreglage, justeras med mus. Värde B, ska vara relativt till värde A. Värde B ska med andra ord få sitt värde beroende på vilket siffervärde som A för närvarande står på. Jag inhämtar värdet A, och vill omvandla detta värde genom en automatisk omräkning, för att resultatet av omräkningen ska bli Bs värde. Värde A styr alltså vilket värde som finns i värde B.

Problemet jag har, är att jag har svårt att hitta bra sätt att räkna om värde A till vad B behöver vara, alltså rent matematiskt, för min matte är lite kass.

Skjutreglagets värde (A) kan varieras mellan minus 18 och plus 18. Detta A-värde ska räknas om, till att bli ett värde mellan 2,5 och 0,3, hela tiden relativt till A-värdet. Med andra ord, när A-värdet står på plus eller minus 18 så ska B-värdet vara 0,3. Och när As värde är noll (mitt emellan minus 18 och plus 18) så ska Bs värde vara 2,5. Bs värde ska förstås omräknas gradvis däremellan 0,3 och 2,5 relativt As värde.

Ett av dom större hindren jag haft, är att värde B får aldrig bli negativt, alltså aldrig hamna på minus-sidan, får inte bli -2,5 till -0,3. Måste hela tiden vara positivt 0,3 - 2,5.

Jag har testat med kvadratrötter och kombinationsmodeller som f*n, men tvingas medge att min matte inte räcker till för att klura fram från scratch hur man kan ställa upp en sån omräkning på enkelt sätt. Det rör alltså bara det matematiska. Att sen formulera det i kod ska inte vara några problem.

Skulle som sagt uppskatta lite hjälp med att skapa en omvandlingsmodell, och även förstå lite hur den fungerar och hur man kan justera den lite i efterhand, vid behov.

Tackar för tips och hjälp

Permalänk
Medlem

Dokumentationen för EEL verkar inte direkt vara den bästa, men enligt detta testscript så verkar det som att det likt många språk har en abs-funktion du kan använda för att ta fram absolutvärdet av ett tal. I så fall borde det bli B = ((18-abs(A)) / 18) * (2,5 - 0,3) + 0,3.

Permalänk
Medlem

Eller enklare: B = 2,5 - 2,2/18 * abs(A)

--------------------

Ett linjärt samband kan beskrivas med det som i matematiken är känt som “den räta linjens ekvation”, y = kx + m.

Vi har två intressanta intervall att undersöka, dels det där x är positivt (intervallet [0; 18]), dels det där x är negativt (intervallet [-18; 0]).

---

Fall 1, x är positivt:

För att beräkna linjens lutning, det s.k. k-värdet, utgår man från två kända punkter på linjen. Vi har exempelvis punkterna (18; 0,3) samt (0; 2,5).
k = (y2 - y1) / (x2 - x1) = (2,5 - 0,3) / (0 - 18) = -2,2/18

Insättning av en känd punkt, exempelvis (0; 2,5) i ekvationen ger värdet på konstanten m.
y = -2,2/18 * x + m => 2,5 = -2,2/18 * 0 + m => m = 2,5

Ekvationen är alltså y = -2,2/18 * x + 2,5 vilket kan skrivas som y = 2,5 - 2,2/18 * x

---

Fall 2, x är negativt:

För att beräkna linjens lutning, det s.k. k-värdet, utgår man från två kända punkter på linjen. Vi har exempelvis punkterna (-18; 0,3) samt (0; 2,5).
k = (y2 - y1) / (x2 - x1) = (2,5 - 0,3) / (0 - (-18)) = 2,2/18

Insättning av en känd punkt, exempelvis (0; 2,5) i ekvationen ger värdet på konstanten m.
y = 2,2/18 * x + m => 2,5 = 2,2/18 * 0 + m => m = 2,5

Ekvationen är alltså y = 2,2/18 * x + 2,5 vilket kan skrivas som y = 2,5 + 2,2/18 * x

---

Den fullständiga ekvationen är alltså
1) y = 2,5 - 2,2/18 * x när 0 <= x <= 18
2) y = 2,5 + 2,2/18 * x när -18 <= x <= 0

Vad gäller del 1 så vet vi att x aldrig är negativt, alltså x = abs(x)
y = 2,5 - 2,2/18 * x => y = 2,5 - 2,2/18 * abs(x)

Vad gäller del 2 så vet vi att x aldrig är positivt, alltså x = (-1) * abs(x)
y = 2,5 + 2,2/18 * x => y = 2,5 + 2,2/18 * (-1) * abs(x) = 2,5 + (-1) * 2,2/18 * abs(x) = 2,5 - 2,2/18 * abs(x)

Den fullständiga ekvationen kan således skrivas
y = 2,5 - 2,2/18 * abs(x) när -18 <= x <= 18

Visa signatur

Laptop: Dell Latitude E7270 | 12,5" FHD IPS | i5-6300U | 16GB RAM | 500GB SSD
Laptop: MacBook Air 13"
NUC: Intel i5-4250U | 8GB RAM | 250GB SSD

Permalänk
Medlem

Om det inte finns en abs() redan så kan man skriva en egen.

function myAbs(value) { if (value < 0) { return (-1) * value; } return value; }

Visa signatur

Herman

Permalänk
Medlem

Hade ett liknande bekymmer (om jag förstår dig rätt) och hittade en bra formel för det du kan få testa när jag är hemma ikväll (kan den inte utantill
Man anger vad högsta och lägsta värde för A får vara och sedan samma sak för värde b, så omvandlar den värdena åt en.
Lite som map-funktionen i arduino om du känner till det.

Kan vara så att något av svaren ovan gör samma sak

Visa signatur

I5 9600k@stock / Cooler Master Evo 212 / Gigabyte Z390 Gaming X / Corsair Vengeance LPX 16GB DDR4 3000MHz / MSI RTX2070 Gaming Z / EVGA 550 BQ / Asus VG27BQ 27" 165Hz

Ryzen 5 5600x@stock / Asus Rog Strix X570-E Gaming / Corsair Vengeance RGB Pro 16GB 3600MHz CL18 / MSI RTX3070 Suprim X / BeQuiet Pure Power 11 600W / Asus VG278Q 27" 144Hz

Permalänk
Medlem

omvandlat = (abs(värdefrånslider) / 18) * (0.3 - 2.5) + 2.5;

Det var den här formeln jag pratade om ovan
Och det fungerar fint när jag testar den.

Men ser att svaren ovanför verkar också fungera!.

edit : såhär kan den också skrivas :

omvandlatvärde = ((faktiskt värde du får in - lägsta värde du kan få in) / (högsta värde du kan få in - lägsta värde du kan få in)) * (högsta omvandlade värde ut - lägsta omvandlade värde ut ) + lägsta omvandlade värde ut.

Visa signatur

I5 9600k@stock / Cooler Master Evo 212 / Gigabyte Z390 Gaming X / Corsair Vengeance LPX 16GB DDR4 3000MHz / MSI RTX2070 Gaming Z / EVGA 550 BQ / Asus VG27BQ 27" 165Hz

Ryzen 5 5600x@stock / Asus Rog Strix X570-E Gaming / Corsair Vengeance RGB Pro 16GB 3600MHz CL18 / MSI RTX3070 Suprim X / BeQuiet Pure Power 11 600W / Asus VG278Q 27" 144Hz