Initial commit
This commit is contained in:
commit
58ee87a861
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/.idea/
|
||||||
|
/vendor/
|
35
bin/app.php
Normal file
35
bin/app.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// http://enjoythemusic.com/diy/0311/crossover.htm
|
||||||
|
|
||||||
|
use Scientific\Frequency;
|
||||||
|
use Scientific\Impedance;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
$frequency = new Frequency(unit(9000));
|
||||||
|
$tweeter = new Driver(new Impedance(unit(8)));
|
||||||
|
$woofer = new Driver(new Impedance(unit(4)));
|
||||||
|
|
||||||
|
$crossover = new FirstOrderTwoWayCrossover($frequency);
|
||||||
|
$capacitor = $crossover->getTweeterCapacitor($tweeter);
|
||||||
|
$inductor = $crossover->getWooferInductor($woofer);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
'First order 2-way crossover @ %s (slope = %s):%s',
|
||||||
|
$crossover->getFrequency(),
|
||||||
|
$crossover->getSlope(),
|
||||||
|
PHP_EOL
|
||||||
|
);
|
||||||
|
printf(
|
||||||
|
' - %s capacitor in series with %s tweeter%s',
|
||||||
|
$capacitor->getCapacitance(),
|
||||||
|
$tweeter->getImpedance(),
|
||||||
|
PHP_EOL
|
||||||
|
);
|
||||||
|
printf(
|
||||||
|
' - %s inductor in series with %s woofer%s',
|
||||||
|
$inductor->getInductance()->format('milli'),
|
||||||
|
$woofer->getImpedance(),
|
||||||
|
PHP_EOL
|
||||||
|
);
|
13
composer.json
Normal file
13
composer.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "joopschilder/speaker-params",
|
||||||
|
"description": "Speaker parameter modelling program",
|
||||||
|
"autoload": {
|
||||||
|
"files": ["src/Lib/helpers.php"],
|
||||||
|
"psr-0": {
|
||||||
|
"": ["src"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/var-dumper": "^5.2"
|
||||||
|
}
|
||||||
|
}
|
270
composer.lock
generated
Normal file
270
composer.lock
generated
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "997f1773a8a4495e430433bfebab7f7c",
|
||||||
|
"packages": [],
|
||||||
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-mbstring",
|
||||||
|
"version": "v1.22.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
|
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
|
||||||
|
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.22-dev"
|
||||||
|
},
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for the Mbstring extension",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"mbstring",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2021-01-22T09:19:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-php80",
|
||||||
|
"version": "v1.22.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
|
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
|
||||||
|
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.22-dev"
|
||||||
|
},
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Php80\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"classmap": [
|
||||||
|
"Resources/stubs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ion Bazan",
|
||||||
|
"email": "ion.bazan@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/var-dumper",
|
||||||
|
"version": "v5.2.6",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/var-dumper.git",
|
||||||
|
"reference": "89412a68ea2e675b4e44f260a5666729f77f668e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/89412a68ea2e675b4e44f260a5666729f77f668e",
|
||||||
|
"reference": "89412a68ea2e675b4e44f260a5666729f77f668e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/polyfill-mbstring": "~1.0",
|
||||||
|
"symfony/polyfill-php80": "^1.15"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpunit/phpunit": "<5.4.3",
|
||||||
|
"symfony/console": "<4.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"symfony/console": "^4.4|^5.0",
|
||||||
|
"symfony/process": "^4.4|^5.0",
|
||||||
|
"twig/twig": "^2.13|^3.0.4"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
|
||||||
|
"ext-intl": "To show region name in time zone dump",
|
||||||
|
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"Resources/bin/var-dump-server"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"Resources/functions/dump.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\VarDumper\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides mechanisms for walking through any arbitrary PHP variable",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"debug",
|
||||||
|
"dump"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/var-dumper/tree/v5.2.6"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2021-03-28T09:42:18+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": [],
|
||||||
|
"plugin-api-version": "2.0.0"
|
||||||
|
}
|
19
src/Components/Capacitor.php
Normal file
19
src/Components/Capacitor.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
19
src/Components/Inductor.php
Normal file
19
src/Components/Inductor.php
Normal 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
17
src/Driver.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
44
src/FirstOrderTwoWayCrossover.php
Normal file
44
src/FirstOrderTwoWayCrossover.php
Normal 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
10
src/Lib/helpers.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Scientific\Unit;
|
||||||
|
|
||||||
|
if (!function_exists('unit')) {
|
||||||
|
function unit(float $value): Unit
|
||||||
|
{
|
||||||
|
return new Unit($value);
|
||||||
|
}
|
||||||
|
}
|
16
src/Scientific/Capacitance.php
Normal file
16
src/Scientific/Capacitance.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Scientific;
|
||||||
|
|
||||||
|
class Capacitance extends Quantity
|
||||||
|
{
|
||||||
|
protected function getSymbol(): string
|
||||||
|
{
|
||||||
|
return 'F';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getName(): string
|
||||||
|
{
|
||||||
|
return 'farad';
|
||||||
|
}
|
||||||
|
}
|
26
src/Scientific/CrossoverSlope.php
Normal file
26
src/Scientific/CrossoverSlope.php
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
16
src/Scientific/Frequency.php
Normal file
16
src/Scientific/Frequency.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Scientific;
|
||||||
|
|
||||||
|
class Frequency extends Quantity
|
||||||
|
{
|
||||||
|
protected function getSymbol(): string
|
||||||
|
{
|
||||||
|
return 'Hz';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getName(): string
|
||||||
|
{
|
||||||
|
return 'hertz';
|
||||||
|
}
|
||||||
|
}
|
7
src/Scientific/Impedance.php
Normal file
7
src/Scientific/Impedance.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Scientific;
|
||||||
|
|
||||||
|
class Impedance extends Resistance
|
||||||
|
{
|
||||||
|
}
|
16
src/Scientific/Inductance.php
Normal file
16
src/Scientific/Inductance.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Scientific;
|
||||||
|
|
||||||
|
class Inductance extends Quantity
|
||||||
|
{
|
||||||
|
protected function getSymbol(): string
|
||||||
|
{
|
||||||
|
return 'H';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getName(): string
|
||||||
|
{
|
||||||
|
return 'henry';
|
||||||
|
}
|
||||||
|
}
|
86
src/Scientific/Quantity.php
Normal file
86
src/Scientific/Quantity.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
16
src/Scientific/Resistance.php
Normal file
16
src/Scientific/Resistance.php
Normal 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
117
src/Scientific/Unit.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user