Initial commit

This commit is contained in:
2021-04-29 21:58:02 +02:00
commit 58ee87a861
17 changed files with 729 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<?php
namespace Components;
use Scientific\Capacitance;
class Capacitor
{
public function __construct(
private float $capacitance
)
{
}
public function getCapacitance(): Capacitance
{
return Capacitance::fromValue($this->capacitance);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Components;
use Scientific\Inductance;
class Inductor
{
public function __construct(
private float $inductance
)
{
}
public function getInductance(): Inductance
{
return Inductance::fromValue($this->inductance);
}
}

17
src/Driver.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
use Scientific\Impedance;
class Driver
{
public function __construct(
private Impedance $impedance
)
{
}
public function getImpedance(): Impedance
{
return clone $this->impedance;
}
}

View File

@@ -0,0 +1,44 @@
<?php
use Components\Capacitor;
use Components\Inductor;
use Scientific\CrossoverSlope;
use Scientific\Frequency;
class FirstOrderTwoWayCrossover
{
private const PI = 3.1415926535;
private const TWO_PI = 2. * self::PI;
public function __construct(
private Frequency $frequency
)
{
}
public function getFrequency(): Frequency
{
return clone $this->frequency;
}
public function getSlope(): CrossoverSlope
{
return CrossoverSlope::fromDecibelPerOctave(6.);
}
public function getTweeterCapacitor(Driver $driver): Capacitor
{
$f = $this->getFrequency()->getValue()->unit();
$z = $driver->getImpedance()->getValue()->unit();
return new Capacitor(1. / (self::TWO_PI * $f * $z));
}
public function getWooferInductor(Driver $driver): Inductor
{
$f = $this->getFrequency()->getValue()->unit();
$z = $driver->getImpedance()->getValue()->unit();
return new Inductor($z / (self::TWO_PI * $f));
}
}

10
src/Lib/helpers.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
use Scientific\Unit;
if (!function_exists('unit')) {
function unit(float $value): Unit
{
return new Unit($value);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Scientific;
class Capacitance extends Quantity
{
protected function getSymbol(): string
{
return 'F';
}
protected function getName(): string
{
return 'farad';
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Scientific;
class CrossoverSlope extends Quantity
{
public static function fromDecibelPerOctave(float $dbPerOctave): static
{
return static::fromValue($dbPerOctave / 10.);
}
protected function getSymbol(): string
{
return 'B/Oct';
}
protected function getName(): string
{
return 'slope';
}
public function __toString(): string
{
return $this->format('deci');
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Scientific;
class Frequency extends Quantity
{
protected function getSymbol(): string
{
return 'Hz';
}
protected function getName(): string
{
return 'hertz';
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace Scientific;
class Impedance extends Resistance
{
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Scientific;
class Inductance extends Quantity
{
protected function getSymbol(): string
{
return 'H';
}
protected function getName(): string
{
return 'henry';
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Scientific;
use InvalidArgumentException;
abstract class Quantity
{
/*
* https://en.wikipedia.org/wiki/Metric_prefix
*/
private const METRIC_PREFIXES = [
'yotta' => 'Y',
'zetta' => 'Z',
'exa' => 'E',
'peta' => 'P',
'tera' => 'T',
'giga' => 'G',
'mega' => 'M',
'kilo' => 'k',
'hecto' => 'h',
'deca' => 'da',
'unit' => '',
'deci' => 'd',
'centi' => 'c',
'milli' => 'm',
'micro' => 'μ',
'nano' => 'n',
'pico' => 'p',
'femto' => 'f',
'atto' => 'a',
'zepto' => 'z',
'yocto' => 'y',
];
abstract protected function getSymbol(): string;
abstract protected function getName(): string;
public function __construct(
private Unit $value
)
{
}
final public static function fromValue(float $value): static
{
return new static(new Unit($value));
}
final public function getValue(): Unit
{
return $this->value;
}
final public function format(string $prefix = 'auto'): string
{
if ($prefix === 'auto') {
$prefix = $this->getAppropriatePrefix();
} else if (!method_exists($this->value, $prefix)) {
throw new InvalidArgumentException('Invalid size: ' . $prefix);
}
$value = $this->value->{$prefix}();
$prefix = self::METRIC_PREFIXES[$prefix] ?? '?';
$symbol = $this->getSymbol();
return sprintf('%.3g %s%s', $value, $prefix, $symbol);
}
private function getAppropriatePrefix(): string
{
foreach (array_keys(self::METRIC_PREFIXES) as $prefix) {
$value = $this->value->{$prefix}();
if ($value >= 1. && $value < 1000.) {
return $prefix;
}
}
return 'unit';
}
public function __toString(): string
{
return $this->format();
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Scientific;
class Resistance extends Quantity
{
protected function getSymbol(): string
{
return 'Ω';
}
protected function getName(): string
{
return 'ohm';
}
}

117
src/Scientific/Unit.php Normal file
View File

@@ -0,0 +1,117 @@
<?php
namespace Scientific;
class Unit
{
public function __construct(
private float $value
)
{
}
public function yotta(): float
{
return $this->zetta() / 1000.;
}
public function zetta(): float
{
return $this->exa() / 1000.;
}
public function exa(): float
{
return $this->peta() / 1000.;
}
public function peta(): float
{
return $this->tera() / 1000.;
}
public function tera(): float
{
return $this->giga() / 1000.;
}
public function giga(): float
{
return $this->mega() / 1000.;
}
public function mega(): float
{
return $this->kilo() / 1000.;
}
public function kilo(): float
{
return $this->unit() / 1000.;
}
public function hecto(): float
{
return $this->unit() / 100.;
}
public function deca(): float
{
return $this->unit() / 10.;
}
public function unit(): float
{
return $this->value;
}
public function deci(): float
{
return 10. * $this->unit();
}
public function centi(): float
{
return 100. * $this->unit();
}
public function milli(): float
{
return 1000. * $this->unit();
}
public function micro(): float
{
return 1000. * $this->milli();
}
public function nano(): float
{
return 1000. * $this->micro();
}
public function pico(): float
{
return 1000. * $this->nano();
}
public function femto(): float
{
return 1000. * $this->pico();
}
public function atto(): float
{
return 1000. * $this->femto();
}
public function zepto(): float
{
return 1000. * $this->atto();
}
public function yocto(): float
{
return 1000. * $this->yocto();
}
}