aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam-anthony <samanthony6@protonmail.com>2022-03-31 20:27:39 -0230
committersam-anthony <samanthony6@protonmail.com>2022-03-31 20:27:39 -0230
commit6634b3ff6bcdffbab38a049460ae6ea3cd68944f (patch)
tree4cbcb7829060883afe074854a2ffc82b4ab2e31b
parentcc0d171c5cd1057693960b7f63aee29e7f70ee8e (diff)
downloadvolute-6634b3ff6bcdffbab38a049460ae6ea3cd68944f.zip
refactor and compressor map image widget
-rw-r--r--compressor/compressor.go45
-rw-r--r--compressor/res/GarrettG25660.jpgbin0 -> 833764 bytes
-rw-r--r--main.go91
-rw-r--r--mass.go86
-rw-r--r--mass/mass.go86
-rw-r--r--pressure.go58
-rw-r--r--pressure/pressure.go58
-rw-r--r--temperature.go71
-rw-r--r--temperature/temperature.go71
-rw-r--r--ui.go116
-rw-r--r--util.go27
-rw-r--r--util/util.go31
-rw-r--r--volume.go54
-rw-r--r--volume/volume.go54
14 files changed, 482 insertions, 366 deletions
diff --git a/compressor/compressor.go b/compressor/compressor.go
new file mode 100644
index 0000000..a3ac4bf
--- /dev/null
+++ b/compressor/compressor.go
@@ -0,0 +1,45 @@
+package compressor
+
+import (
+ "time"
+
+ "github.com/sam-anthony/volute/mass"
+ "github.com/sam-anthony/volute/util"
+)
+
+type Compressor struct {
+ FileName string
+ // MinX is the distance of the y-axis from left of image in pixels.
+ MinX int
+ // MinY is the distance of the x-axis from the top of the image in
+ //pixels.
+ MinY int
+ // MaxX is the distance of the end of the graph from the left of the
+ // image in pixels.
+ MaxX int
+ // MaxY is the distance of the top of the graph from the top of the
+ // image in pixels.
+ MaxY int
+ // MaxFlow is the mass flow rate at MaxX.
+ MaxFlow mass.FlowRate
+ // MaxPressureRatio is the pressure ratio at MaxY.
+ MaxPressureRatio float32
+}
+
+func GarrettG25660() Compressor {
+ maxFlow, err := mass.NewFlowRate(
+ mass.Mass{70, mass.Pound},
+ time.Minute,
+ mass.PoundsPerMinute,
+ )
+ util.Check(err)
+ return Compressor{
+ "compressor/res/GarrettG25660.jpg",
+ 204,
+ 1885,
+ 1665,
+ 25,
+ maxFlow,
+ 4.0,
+ }
+}
diff --git a/compressor/res/GarrettG25660.jpg b/compressor/res/GarrettG25660.jpg
new file mode 100644
index 0000000..aa8d12a
--- /dev/null
+++ b/compressor/res/GarrettG25660.jpg
Binary files differ
diff --git a/main.go b/main.go
index 4af9cbb..82847bd 100644
--- a/main.go
+++ b/main.go
@@ -2,7 +2,18 @@ package main
import (
g "github.com/AllenDang/giu"
+ "image"
+ "image/draw"
+ _ "image/jpeg"
+ "os"
"time"
+
+ "github.com/sam-anthony/volute/compressor"
+ "github.com/sam-anthony/volute/mass"
+ "github.com/sam-anthony/volute/pressure"
+ "github.com/sam-anthony/volute/temperature"
+ "github.com/sam-anthony/volute/util"
+ "github.com/sam-anthony/volute/volume"
)
const (
@@ -14,29 +25,29 @@ const (
var numPoints = 1
var (
- displacement = volume{2000, cubicCentimetre}
- // selectedVolumeUnit is used to index volumeUnitStrings.
- selectedVolumeUnit = defaultVolumeUnitIndex
+ displacement = volume.Volume{2000, volume.CubicCentimetre}
+ // selectedVolumeUnit is used to index volume.UnitStrings().
+ selectedVolumeUnit = volume.DefaultUnitIndex
engineSpeed = []int32{2000}
volumetricEfficiency = []int32{80}
- intakeAirTemperature = []temperature{{25, celcius}}
- // selectedTemperatureUnit is used to index temperatureUnitStrings.
- selectedTemperatureUnit = defaultTemperatureUnitIndex
+ intakeAirTemperature = []temperature.Temperature{{25, temperature.Celcius}}
+ // selectedTemperatureUnit is used to index temperature.UnitStrings().
+ selectedTemperatureUnit = temperature.DefaultUnitIndex
- manifoldPressure = []pressure{{100, defaultPressureUnit}}
- // selectedPressureUnit is used to index pressureUnitStrings.
- selectedPressureUnit = defaultPressureUnitIndex
+ manifoldPressure = []pressure.Pressure{{100, pressure.DefaultUnit}}
+ // selectedPressureUnit is used to index pressure.UnitStrings().
+ selectedPressureUnit = pressure.DefaultUnitIndex
)
var pressureRatio []float32
func pressureRatioAt(point int) float32 {
- u := pascal
- m := manifoldPressure[point].asUnit(u)
- a := atmosphericPressure().asUnit(u)
+ u := pressure.Pascal
+ m := manifoldPressure[point].AsUnit(u)
+ a := pressure.Atmospheric().AsUnit(u)
return m / a
}
func init() {
@@ -44,31 +55,31 @@ func init() {
}
var (
- engineMassFlowRate []massFlowRate
- // selectedMassFlowRateUnit is used to index massFlowRateUnitStrings.
- selectedMassFlowRateUnit = defaultMassFlowRateUnitIndex
+ engineMassFlowRate []mass.FlowRate
+ // selectedMassFlowRateUnit is used to index mass.FlowRateUnitStrings().
+ selectedMassFlowRateUnit = mass.DefaultFlowRateUnitIndex
)
-func massFlowRateAt(point int) massFlowRate {
+func massFlowRateAt(point int) mass.FlowRate {
rpm := float32(engineSpeed[point])
- disp := displacement.asUnit(cubicMetre)
+ disp := displacement.AsUnit(volume.CubicMetre)
ve := float32(volumetricEfficiency[point]) / 100.0
cubicMetresPerMin := (rpm / 2.0) * disp * ve
- iat, err := intakeAirTemperature[point].asUnit(kelvin)
- check(err)
- pres := manifoldPressure[point].asUnit(pascal)
+ iat, err := intakeAirTemperature[point].AsUnit(temperature.Kelvin)
+ util.Check(err)
+ pres := manifoldPressure[point].AsUnit(pressure.Pascal)
molsPerMin := (pres * cubicMetresPerMin) / (gasConstant * iat)
kgPerMin := molsPerMin * airMolarMass
- massPerMin := mass{kgPerMin, kilogram}
+ massPerMin := mass.Mass{kgPerMin, mass.Kilogram}
- u, err := massFlowRateUnitFromString(massFlowRateUnitStrings()[selectedMassFlowRateUnit])
- check(err)
+ u, err := mass.FlowRateUnitFromString(mass.FlowRateUnitStrings()[selectedMassFlowRateUnit])
+ util.Check(err)
- mfr, err := newMassFlowRate(massPerMin, time.Minute, u)
- check(err)
+ mfr, err := mass.NewFlowRate(massPerMin, time.Minute, u)
+ util.Check(err)
return mfr
}
func init() {
@@ -79,6 +90,7 @@ func loop() {
g.SingleWindow().Layout(
engineDisplacementRow(),
g.Table().
+ Size(g.Auto, 190).
Rows(
engineSpeedRow(),
volumetricEfficiencyRow(),
@@ -91,10 +103,39 @@ func loop() {
Columns(
columns()...,
),
+ g.Custom(compressorWidget),
)
}
+var (
+ compressorImage *image.RGBA
+ compressorTexture *g.Texture
+ selectedCompressor compressor.Compressor
+)
+
+func init() {
+ selectedCompressor = compressor.GarrettG25660()
+
+ f, err := os.Open(selectedCompressor.FileName)
+ util.Check(err)
+ defer f.Close()
+
+ j, _, err := image.Decode(f)
+ util.Check(err)
+
+ b := j.Bounds()
+ m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
+ draw.Draw(m, m.Bounds(), j, b.Min, draw.Src)
+
+ compressorImage = m
+}
+
func main() {
wnd := g.NewMasterWindow("volute", 400, 200, 0)
+
+ g.EnqueueNewTextureFromRgba(compressorImage, func(tex *g.Texture) {
+ compressorTexture = tex
+ })
+
wnd.Run(loop)
}
diff --git a/mass.go b/mass.go
deleted file mode 100644
index 0b97020..0000000
--- a/mass.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package main
-
-import (
- "errors"
- "fmt"
- "time"
-)
-
-type massUnit float32
-
-const (
- gram massUnit = 1
- kilogram massUnit = 1_000
- pound massUnit = 453.5924
-)
-
-type mass struct {
- val float32
- unit massUnit
-}
-
-func (m mass) asUnit(u massUnit) float32 {
- g := m.val * float32(m.unit) // Convert to grams.
- return g / float32(u) // Convert to desired unit.
-}
-
-type massFlowRateUnit float32
-
-const (
- kilogramsPerSecond massFlowRateUnit = 1
- poundsPerMinute massFlowRateUnit = 0.007_559_872_833
-)
-
-// massFlowRateUnitStrings returns a slice of strings, each representing a
-// massFlowRateUnit.
-// This is necessary because giu.Combo only works with strings.
-func massFlowRateUnitStrings() []string {
- return []string{"kg/s", "lb/min"}
-}
-
-const (
- defaultMassFlowRateUnit massFlowRateUnit = kilogramsPerSecond
- //Used to index massFlowRateUnitStrings
- defaultMassFlowRateUnitIndex int32 = 0 // kg/s
-)
-
-func massFlowRateUnitFromString(s string) (massFlowRateUnit, error) {
- // Each case corresponds to a value in massFlowRateUnitStrings.
- switch s {
- case "kg/s":
- return kilogramsPerSecond, nil
- case "lb/min":
- return poundsPerMinute, nil
- default:
- return *new(massFlowRateUnit), errors.New(
- fmt.Sprintf("invalid massFlowRateUnit: '%s'", s))
- }
-}
-
-type massFlowRate struct {
- val float32
- unit massFlowRateUnit
-}
-
-func newMassFlowRate(m mass, t time.Duration, u massFlowRateUnit) (massFlowRate, error) {
- switch u {
- case kilogramsPerSecond:
- return massFlowRate{
- m.asUnit(kilogram) / float32(t.Seconds()),
- u,
- }, nil
- case poundsPerMinute:
- return massFlowRate{
- m.asUnit(pound) / float32(t.Minutes()),
- u,
- }, nil
- default:
- return *new(massFlowRate), errors.New(
- fmt.Sprintf("invalid massFlowRateUnit: '%v'", u))
- }
-}
-
-func (fr massFlowRate) asUnit(u massFlowRateUnit) float32 {
- kgps := fr.val * float32(fr.unit) // Convert to kilogramsPerSecond.
- return kgps / float32(u) // Convert to desired unit.
-}
diff --git a/mass/mass.go b/mass/mass.go
new file mode 100644
index 0000000..29ecbd5
--- /dev/null
+++ b/mass/mass.go
@@ -0,0 +1,86 @@
+package mass
+
+import (
+ "errors"
+ "fmt"
+ "time"
+)
+
+type unit float32
+
+const (
+ Gram unit = 1
+ Kilogram unit = 1_000
+ Pound unit = 453.5924
+)
+
+type Mass struct {
+ Val float32
+ Unit unit
+}
+
+func (m Mass) AsUnit(u unit) float32 {
+ g := m.Val * float32(m.Unit) // Convert to grams.
+ return g / float32(u) // Convert to desired unit.
+}
+
+type flowRateUnit float32
+
+const (
+ KilogramsPerSecond flowRateUnit = 1
+ PoundsPerMinute flowRateUnit = 0.007_559_872_833
+)
+
+// FlowRateUnitStrings returns a slice of strings, each representing a
+// flowRateUnit.
+// This is necessary because giu.Combo only works with strings.
+func FlowRateUnitStrings() []string {
+ return []string{"kg/s", "lb/min"}
+}
+
+const (
+ DefaultFlowRateUnit flowRateUnit = KilogramsPerSecond
+ // DefaultFlowRateUnitIndex is used to index FlowRateUnitStrings()
+ DefaultFlowRateUnitIndex int32 = 0 // kg/s
+)
+
+func FlowRateUnitFromString(s string) (flowRateUnit, error) {
+ // Each case corresponds to a value in FlowRateUnitStrings().
+ switch s {
+ case "kg/s":
+ return KilogramsPerSecond, nil
+ case "lb/min":
+ return PoundsPerMinute, nil
+ default:
+ return *new(flowRateUnit), errors.New(
+ fmt.Sprintf("invalid massFlowRateUnit: '%s'", s))
+ }
+}
+
+type FlowRate struct {
+ Val float32
+ Unit flowRateUnit
+}
+
+func NewFlowRate(m Mass, t time.Duration, u flowRateUnit) (FlowRate, error) {
+ switch u {
+ case KilogramsPerSecond:
+ return FlowRate{
+ m.AsUnit(Kilogram) / float32(t.Seconds()),
+ u,
+ }, nil
+ case PoundsPerMinute:
+ return FlowRate{
+ m.AsUnit(Pound) / float32(t.Minutes()),
+ u,
+ }, nil
+ default:
+ return *new(FlowRate), errors.New(
+ fmt.Sprintf("invalid massFlowRateUnit: '%v'", u))
+ }
+}
+
+func (fr FlowRate) AsUnit(u flowRateUnit) float32 {
+ kgps := fr.Val * float32(fr.Unit) // Convert to kilogramsPerSecond.
+ return kgps / float32(u) // Convert to desired unit.
+}
diff --git a/pressure.go b/pressure.go
deleted file mode 100644
index a6665dc..0000000
--- a/pressure.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package main
-
-import (
- "errors"
- "fmt"
-)
-
-type pressureUnit float32
-
-const (
- pascal pressureUnit = 1
- kilopascal pressureUnit = 1_000
- bar pressureUnit = 100_000
- poundsPerSquareInch pressureUnit = 6_894.757
-)
-
-// pressureUnitStrings returns a slice of strings, each representing a
-// pressureUnit.
-// This is necessary because giu.Combo only works with strings.
-func pressureUnitStrings() []string {
- return []string{"Pa", "kPa", "bar", "psi"}
-}
-
-const (
- defaultPressureUnit pressureUnit = kilopascal
- // Used to index pressureUnitStrings
- defaultPressureUnitIndex int32 = 1 // kPa
-)
-
-func pressureUnitFromString(s string) (pressureUnit, error) {
- // Each case corresponds to a value in pressureUnitStrings
- switch s {
- case "Pa":
- return pascal, nil
- case "kPa":
- return kilopascal, nil
- case "bar":
- return bar, nil
- case "psi":
- return poundsPerSquareInch, nil
- default:
- return *new(pressureUnit), errors.New(fmt.Sprintf("invalid pressureUnit: '%s'", s))
- }
-}
-
-type pressure struct {
- val float32
- unit pressureUnit
-}
-
-func (p pressure) asUnit(u pressureUnit) float32 {
- pa := p.val * float32(p.unit) // Convert to pascals.
- return pa / float32(u) // Convert to desired unit.
-}
-
-func atmosphericPressure() pressure {
- return pressure{1, bar}
-}
diff --git a/pressure/pressure.go b/pressure/pressure.go
new file mode 100644
index 0000000..2948c72
--- /dev/null
+++ b/pressure/pressure.go
@@ -0,0 +1,58 @@
+package pressure
+
+import (
+ "errors"
+ "fmt"
+)
+
+type unit float32
+
+const (
+ Pascal unit = 1
+ Kilopascal unit = 1_000
+ Bar unit = 100_000
+ PoundsPerSquareInch unit = 6_894.757
+)
+
+// UnitStrings returns a slice of strings, each representing a
+// unit.
+// This is necessary because giu.Combo only works with strings.
+func UnitStrings() []string {
+ return []string{"Pa", "kPa", "bar", "psi"}
+}
+
+const (
+ DefaultUnit unit = Kilopascal
+ // DefaultUnitIndex is used to index UnitStrings().
+ DefaultUnitIndex int32 = 1 // kPa
+)
+
+func UnitFromString(s string) (unit, error) {
+ // Each case corresponds to a value in UnitStrings().
+ switch s {
+ case "Pa":
+ return Pascal, nil
+ case "kPa":
+ return Kilopascal, nil
+ case "bar":
+ return Bar, nil
+ case "psi":
+ return PoundsPerSquareInch, nil
+ default:
+ return *new(unit), errors.New(fmt.Sprintf("invalid unit: '%s'", s))
+ }
+}
+
+type Pressure struct {
+ Val float32
+ Unit unit
+}
+
+func (p Pressure) AsUnit(u unit) float32 {
+ pa := p.Val * float32(p.Unit) // Convert to pascals.
+ return pa / float32(u) // Convert to desired unit.
+}
+
+func Atmospheric() Pressure {
+ return Pressure{1, Bar}
+}
diff --git a/temperature.go b/temperature.go
deleted file mode 100644
index 7562ca7..0000000
--- a/temperature.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package main
-
-import (
- "errors"
- "fmt"
-)
-
-type temperatureUnit int
-
-const (
- celcius temperatureUnit = iota
- kelvin
- fahrenheit
-)
-
-// temperatureUnitStrings returns a slice of strings, each representing a
-// temperatureUnit.
-// This is necessary because giu.Combo only works with strings.
-func temperatureUnitStrings() []string {
- return []string{"°C", "°K", "°F"}
-}
-
-const (
- defaultTemperatureUnit temperatureUnit = celcius
- // Used to index temperatureUnitStrings
- defaultTemperatureUnitIndex int32 = 0 // celcius
-)
-
-func temperatureUnitFromString(s string) (temperatureUnit, error) {
- // Each case corresponds to a value in volumeUnitStrings.
- switch s {
- case "°C":
- return celcius, nil
- case "°K":
- return kelvin, nil
- case "°F":
- return fahrenheit, nil
- default:
- return *new(temperatureUnit), errors.New(fmt.Sprintf("invalid temperatureUnit: '%s'", s))
- }
-}
-
-type temperature struct {
- val float32
- unit temperatureUnit
-}
-
-func (t temperature) asUnit(u temperatureUnit) (float32, error) {
- // Convert to celcius
- var c float32
- switch t.unit {
- case celcius:
- c = t.val
- case kelvin:
- c = t.val - 272.15
- case fahrenheit:
- c = (t.val - 32.0) * (5.0 / 9.0)
- }
-
- // Convert to desired unit
- switch u {
- case celcius:
- return c, nil
- case kelvin:
- return c + 272.15, nil
- case fahrenheit:
- return c*(9.0/5.0) + 32.0, nil
- default:
- return 0, errors.New(fmt.Sprintf("invalid temperatureUnit: '%v'", u))
- }
-}
diff --git a/temperature/temperature.go b/temperature/temperature.go
new file mode 100644
index 0000000..2a135df
--- /dev/null
+++ b/temperature/temperature.go
@@ -0,0 +1,71 @@
+package temperature
+
+import (
+ "errors"
+ "fmt"
+)
+
+type unit int
+
+const (
+ Celcius unit = iota
+ Kelvin
+ Fahrenheit
+)
+
+// UnitStrings returns a slice of strings, each representing a
+// unit.
+// This is necessary because giu.Combo only works with strings.
+func UnitStrings() []string {
+ return []string{"°C", "°K", "°F"}
+}
+
+const (
+ DefaultUnit unit = Celcius
+ // DefaultUnitIndex is used to index UnitStrings().
+ DefaultUnitIndex int32 = 0 // celcius
+)
+
+func UnitFromString(s string) (unit, error) {
+ // Each case corresponds to a value in UnitStrings().
+ switch s {
+ case "°C":
+ return Celcius, nil
+ case "°K":
+ return Kelvin, nil
+ case "°F":
+ return Fahrenheit, nil
+ default:
+ return *new(unit), errors.New(fmt.Sprintf("invalid unit: '%s'", s))
+ }
+}
+
+type Temperature struct {
+ Val float32
+ Unit unit
+}
+
+func (t Temperature) AsUnit(u unit) (float32, error) {
+ // Convert to celcius
+ var c float32
+ switch t.Unit {
+ case Celcius:
+ c = t.Val
+ case Kelvin:
+ c = t.Val - 272.15
+ case Fahrenheit:
+ c = (t.Val - 32.0) * (5.0 / 9.0)
+ }
+
+ // Convert to desired unit
+ switch u {
+ case Celcius:
+ return c, nil
+ case Kelvin:
+ return c + 272.15, nil
+ case Fahrenheit:
+ return c*(9.0/5.0) + 32.0, nil
+ default:
+ return 0, errors.New(fmt.Sprintf("invalid unit: '%v'", u))
+ }
+}
diff --git a/ui.go b/ui.go
index b12ff07..0515c46 100644
--- a/ui.go
+++ b/ui.go
@@ -3,28 +3,35 @@ package main
import (
"fmt"
g "github.com/AllenDang/giu"
+ "image"
"strconv"
+
+ "github.com/sam-anthony/volute/mass"
+ "github.com/sam-anthony/volute/pressure"
+ "github.com/sam-anthony/volute/temperature"
+ "github.com/sam-anthony/volute/util"
+ "github.com/sam-anthony/volute/volume"
)
func engineDisplacementRow() *g.RowWidget {
return g.Row(
g.Label("Engine Displacement"),
- g.InputFloat(&displacement.val).Format("%.2f").OnChange(func() {
+ g.InputFloat(&displacement.Val).Format("%.2f").OnChange(func() {
for i := 0; i < numPoints; i++ {
engineMassFlowRate[i] = massFlowRateAt(i)
}
}),
g.Combo(
"",
- volumeUnitStrings()[selectedVolumeUnit],
- volumeUnitStrings(),
+ volume.UnitStrings()[selectedVolumeUnit],
+ volume.UnitStrings(),
&selectedVolumeUnit,
).OnChange(func() {
- s := volumeUnitStrings()[selectedVolumeUnit]
- u, err := volumeUnitFromString(s)
- check(err)
- displacement = volume{
- displacement.asUnit(u),
+ s := volume.UnitStrings()[selectedVolumeUnit]
+ u, err := volume.UnitFromString(s)
+ util.Check(err)
+ displacement = volume.Volume{
+ displacement.AsUnit(u),
u,
}
}),
@@ -70,18 +77,18 @@ func intakeAirTemperatureRow() *g.TableRowWidget {
g.Label("Intake Air Temperature"),
g.Combo(
"",
- temperatureUnitStrings()[selectedTemperatureUnit],
- temperatureUnitStrings(),
+ temperature.UnitStrings()[selectedTemperatureUnit],
+ temperature.UnitStrings(),
&selectedTemperatureUnit,
).OnChange(func() {
- s := temperatureUnitStrings()[selectedTemperatureUnit]
- u, err := temperatureUnitFromString(s)
- check(err)
+ s := temperature.UnitStrings()[selectedTemperatureUnit]
+ u, err := temperature.UnitFromString(s)
+ util.Check(err)
for i := range intakeAirTemperature {
- t, err := intakeAirTemperature[i].asUnit(u)
- check(err)
- intakeAirTemperature[i] = temperature{t, u}
+ t, err := intakeAirTemperature[i].AsUnit(u)
+ util.Check(err)
+ intakeAirTemperature[i] = temperature.Temperature{t, u}
}
}),
}
@@ -89,7 +96,7 @@ func intakeAirTemperatureRow() *g.TableRowWidget {
i := i
widgets = append(
widgets,
- g.InputFloat(&intakeAirTemperature[i].val).
+ g.InputFloat(&intakeAirTemperature[i].Val).
Format("%.2f").
OnChange(func() {
engineMassFlowRate[i] = massFlowRateAt(i)
@@ -104,17 +111,17 @@ func manifoldPressureRow() *g.TableRowWidget {
g.Label("Manifold Absolute Pressure"),
g.Combo(
"",
- pressureUnitStrings()[selectedPressureUnit],
- pressureUnitStrings(),
+ pressure.UnitStrings()[selectedPressureUnit],
+ pressure.UnitStrings(),
&selectedPressureUnit,
).OnChange(func() {
- s := pressureUnitStrings()[selectedPressureUnit]
- u, err := pressureUnitFromString(s)
- check(err)
+ s := pressure.UnitStrings()[selectedPressureUnit]
+ u, err := pressure.UnitFromString(s)
+ util.Check(err)
for i := 0; i < numPoints; i++ {
- manifoldPressure[i] = pressure{
- manifoldPressure[i].asUnit(u),
+ manifoldPressure[i] = pressure.Pressure{
+ manifoldPressure[i].AsUnit(u),
u,
}
}
@@ -124,7 +131,7 @@ func manifoldPressureRow() *g.TableRowWidget {
i := i
widgets = append(
widgets,
- g.InputFloat(&manifoldPressure[i].val).Format("%.2f").
+ g.InputFloat(&manifoldPressure[i].Val).Format("%.2f").
OnChange(func() {
pressureRatio[i] = pressureRatioAt(i)
engineMassFlowRate[i] = massFlowRateAt(i)
@@ -154,17 +161,17 @@ func massFlowRateRow() *g.TableRowWidget {
g.Label("Mass Flow Rate"),
g.Combo(
"",
- massFlowRateUnitStrings()[selectedMassFlowRateUnit],
- massFlowRateUnitStrings(),
+ mass.FlowRateUnitStrings()[selectedMassFlowRateUnit],
+ mass.FlowRateUnitStrings(),
&selectedMassFlowRateUnit,
).OnChange(func() {
- s := massFlowRateUnitStrings()[selectedMassFlowRateUnit]
- u, err := massFlowRateUnitFromString(s)
- check(err)
+ s := mass.FlowRateUnitStrings()[selectedMassFlowRateUnit]
+ u, err := mass.FlowRateUnitFromString(s)
+ util.Check(err)
for i := 0; i < numPoints; i++ {
- engineMassFlowRate[i] = massFlowRate{
- engineMassFlowRate[i].asUnit(u),
+ engineMassFlowRate[i] = mass.FlowRate{
+ engineMassFlowRate[i].AsUnit(u),
u,
}
}
@@ -172,7 +179,7 @@ func massFlowRateRow() *g.TableRowWidget {
}
for i := 0; i < numPoints; i++ {
mfr := strconv.FormatFloat(
- float64(engineMassFlowRate[i].val),
+ float64(engineMassFlowRate[i].Val),
'f',
3,
32,
@@ -192,32 +199,32 @@ func duplicateDeleteRow() *g.TableRowWidget {
widgets = append(widgets, g.Row(
g.Button("Duplicate").OnClick(func() {
numPoints++
- engineSpeed = insert(
+ engineSpeed = util.Insert(
engineSpeed,
engineSpeed[i],
i,
)
- volumetricEfficiency = insert(
+ volumetricEfficiency = util.Insert(
volumetricEfficiency,
volumetricEfficiency[i],
i,
)
- intakeAirTemperature = insert(
+ intakeAirTemperature = util.Insert(
intakeAirTemperature,
intakeAirTemperature[i],
i,
)
- manifoldPressure = insert(
+ manifoldPressure = util.Insert(
manifoldPressure,
manifoldPressure[i],
i,
)
- pressureRatio = insert(
+ pressureRatio = util.Insert(
pressureRatio,
pressureRatio[i],
i,
)
- engineMassFlowRate = insert(
+ engineMassFlowRate = util.Insert(
engineMassFlowRate,
engineMassFlowRate[i],
i,
@@ -228,12 +235,12 @@ func duplicateDeleteRow() *g.TableRowWidget {
return
}
numPoints--
- engineSpeed = remove(engineSpeed, i)
- volumetricEfficiency = remove(volumetricEfficiency, i)
- intakeAirTemperature = remove(intakeAirTemperature, i)
- manifoldPressure = remove(manifoldPressure, i)
- pressureRatio = remove(pressureRatio, i)
- engineMassFlowRate = remove(engineMassFlowRate, i)
+ engineSpeed = util.Remove(engineSpeed, i)
+ volumetricEfficiency = util.Remove(volumetricEfficiency, i)
+ intakeAirTemperature = util.Remove(intakeAirTemperature, i)
+ manifoldPressure = util.Remove(manifoldPressure, i)
+ pressureRatio = util.Remove(pressureRatio, i)
+ engineMassFlowRate = util.Remove(engineMassFlowRate, i)
}),
))
}
@@ -253,3 +260,22 @@ func columns() []*g.TableColumnWidget {
}
return widgets
}
+
+func compressorWidget() {
+ m := compressorImage
+ // TODO: Apply points to compressor map.
+
+ g.EnqueueNewTextureFromRgba(m, func(tex *g.Texture) {
+ compressorTexture = tex
+ })
+
+ canvas := g.GetCanvas()
+ if compressorTexture != nil {
+ winWidth, winHeight := g.GetAvailableRegion()
+ canvas.AddImage(
+ compressorTexture,
+ image.Pt(0, 225),
+ image.Pt(int(winWidth), int(winHeight)),
+ )
+ }
+}
diff --git a/util.go b/util.go
deleted file mode 100644
index c11ff40..0000000
--- a/util.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package main
-
-import (
- "fmt"
- "os"
-)
-
-func check(err error) {
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
-}
-
-func insert[T int32 | float32 | temperature | pressure | massFlowRate](slice []T, elem T, i int) []T {
- return append(
- slice[:i],
- append(
- []T{elem},
- slice[i:]...,
- )...,
- )
-}
-
-func remove[T int32 | float32 | temperature | pressure | massFlowRate](slice []T, i int) []T {
- return append(slice[:i], slice[i+1:]...)
-}
diff --git a/util/util.go b/util/util.go
new file mode 100644
index 0000000..5812ee1
--- /dev/null
+++ b/util/util.go
@@ -0,0 +1,31 @@
+package util
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/sam-anthony/volute/mass"
+ "github.com/sam-anthony/volute/pressure"
+ "github.com/sam-anthony/volute/temperature"
+)
+
+func Check(err error) {
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+
+func Insert[T int32 | float32 | temperature.Temperature | pressure.Pressure | mass.FlowRate](slice []T, elem T, i int) []T {
+ return append(
+ slice[:i],
+ append(
+ []T{elem},
+ slice[i:]...,
+ )...,
+ )
+}
+
+func Remove[T int32 | float32 | temperature.Temperature | pressure.Pressure | mass.FlowRate](slice []T, i int) []T {
+ return append(slice[:i], slice[i+1:]...)
+}
diff --git a/volume.go b/volume.go
deleted file mode 100644
index cb7098a..0000000
--- a/volume.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package main
-
-import (
- "errors"
- "fmt"
-)
-
-type volumeUnit float32
-
-const (
- cubicCentimetre volumeUnit = 1
- litre volumeUnit = 1_000
- cubicMetre volumeUnit = 1_000_000
- cubicInch volumeUnit = 16.38706
-)
-
-// volumeUnitStrings returns a slice of strings, each representing a
-// volumeUnit.
-// This is necessary because giu.Combo only works with strings.
-func volumeUnitStrings() []string {
- return []string{"cc", "L", "m³", "in³"}
-}
-
-const (
- defaultVolumeUnit volumeUnit = cubicCentimetre
- // Used to index volumeUnitStrings
- defaultVolumeUnitIndex int32 = 0 // cc
-)
-
-func volumeUnitFromString(s string) (volumeUnit, error) {
- // Each case corresponds to a value in volumeUnitStrings
- switch s {
- case "cc":
- return cubicCentimetre, nil
- case "L":
- return litre, nil
- case "m³":
- return cubicMetre, nil
- case "in³":
- return cubicInch, nil
- default:
- return *new(volumeUnit), errors.New(fmt.Sprintf("invalid volumeUnit: '%s'", s))
- }
-}
-
-type volume struct {
- val float32
- unit volumeUnit
-}
-
-func (v volume) asUnit(u volumeUnit) float32 {
- cc := v.val * float32(v.unit) // Convert to cubic centimetres.
- return cc / float32(u) // Convert to desired unit.
-}
diff --git a/volume/volume.go b/volume/volume.go
new file mode 100644
index 0000000..020d1a6
--- /dev/null
+++ b/volume/volume.go
@@ -0,0 +1,54 @@
+package volume
+
+import (
+ "errors"
+ "fmt"
+)
+
+type unit float32
+
+const (
+ CubicCentimetre unit = 1
+ Litre unit = 1_000
+ CubicMetre unit = 1_000_000
+ CubicInch unit = 16.38706
+)
+
+// UnitStrings returns a slice of strings, each representing a
+// unit.
+// This is necessary because giu.Combo only works with strings.
+func UnitStrings() []string {
+ return []string{"cc", "L", "m³", "in³"}
+}
+
+const (
+ DefaultUnit unit = CubicCentimetre
+ // DefaulUnitIndex is used to index UnitStrings().
+ DefaultUnitIndex int32 = 0 // cc
+)
+
+func UnitFromString(s string) (unit, error) {
+ // Each case corresponds to a value in UnitStrings().
+ switch s {
+ case "cc":
+ return CubicCentimetre, nil
+ case "L":
+ return Litre, nil
+ case "m³":
+ return CubicMetre, nil
+ case "in³":
+ return CubicInch, nil
+ default:
+ return *new(unit), errors.New(fmt.Sprintf("invalid volume unit: '%s'", s))
+ }
+}
+
+type Volume struct {
+ Val float32
+ Unit unit
+}
+
+func (v Volume) AsUnit(u unit) float32 {
+ cc := v.Val * float32(v.Unit) // Convert to cubic centimetres.
+ return cc / float32(u) // Convert to desired unit.
+}