diff --git a/apps/docs/src/content/docs/conversions/force.mdx b/apps/docs/src/content/docs/conversions/force.mdx new file mode 100644 index 0000000..a0fbee1 --- /dev/null +++ b/apps/docs/src/content/docs/conversions/force.mdx @@ -0,0 +1,38 @@ +--- +title: "Force" +template: doc +--- + +The **force** category supports conversions between Newton, Dyne, Poundal, Pound-Force, and Kilogram-Force. + +## Supported Units + +- Newton `N` +- Dyne `dyn` +- Poundal `pdl` +- Pound-Force `lbf` +- Kilogram-Force `kgf` + +## Quick Example + +```ts +import { Conversion } from "@devhaven/unit-conversion"; + +const convert = new Conversion(); + +convert.value(10).from("newton").to("dyne"); +convert.value(5000).from("dyne").to("newton"); +``` + +## Common Conversions +### Newton ↔ Kilogram-Force +```ts +convert.value(1).from("newton").to("kilogram-force"); +convert.value(1).from("kilogram-force").to("newton"); +``` + +### Newton ↔ Pound-Force +```ts +convert.value(1).from("newton").to("pound-force"); +convert.value(1).from("pound-force").to("newton"); +``` \ No newline at end of file diff --git a/packages/unit-conversion/src/constants/labels.ts b/packages/unit-conversion/src/constants/labels.ts index 7766094..d91fb29 100644 --- a/packages/unit-conversion/src/constants/labels.ts +++ b/packages/unit-conversion/src/constants/labels.ts @@ -111,7 +111,7 @@ export const LABELS = { fahrenheit: "°F", rankine: "°R", delisle: "°De", - newton: "°N", + "newton-degree": "°N", réaumur: "°Ré", rømer: "°Rø", @@ -119,6 +119,13 @@ export const LABELS = { candela: "cd", stilb: "sb", + // Force + newton: "N", + dyne: "dyn", + poundal: "pdl", + "pound-force": "lbf", + "kilogram-force": "kgf", + // pressure pascal: "Pa", kilopascal: "kPa", diff --git a/packages/unit-conversion/src/constants/units.ts b/packages/unit-conversion/src/constants/units.ts index 611e3df..bcb4c7f 100644 --- a/packages/unit-conversion/src/constants/units.ts +++ b/packages/unit-conversion/src/constants/units.ts @@ -27,7 +27,7 @@ export type EnergyUnits = | "kilowatt-hour" | "electron-volt"; export type AngleUnits = "radian" | "degree" | "gradian" | "arcminute" | "arcsecond"; - +export type ForceUnits = "newton" | "dyne" | "pound-force" | "kilogram-force" | "poundal"; export type AllUnits = | TemperatureUnits | LengthUnits @@ -37,7 +37,8 @@ export type AllUnits = | NumberUnits | PressureUnits | EnergyUnits - | AngleUnits; + | AngleUnits + | ForceUnits; export type UnitCategory = T extends TemperatureUnits ? TemperatureUnits @@ -51,13 +52,15 @@ export type UnitCategory = T extends TemperatureUnits ? TimeUnits : T extends NumberUnits ? NumberUnits - : T extends PressureUnits - ? PressureUnits - : T extends EnergyUnits - ? EnergyUnits - : T extends AngleUnits - ? AngleUnits - : never; + : T extends ForceUnits + ? ForceUnits + : T extends PressureUnits + ? PressureUnits + : T extends EnergyUnits + ? EnergyUnits + : T extends AngleUnits + ? AngleUnits + : never; export type ALL_UNIT_CATEGORIES = { temperature: TemperatureUnits[]; @@ -69,6 +72,7 @@ export type ALL_UNIT_CATEGORIES = { pressure: PressureUnits[]; energy: EnergyUnits[]; angle: AngleUnits[]; + force: ForceUnits[]; }; /** @@ -118,6 +122,7 @@ export const UNITS: ALL_UNIT_CATEGORIES = { "electron-volt", ], angle: ["degree", "radian", "gradian", "arcminute", "arcsecond"], + force: ["newton", "dyne", "pound-force", "kilogram-force", "poundal"], }; export const NO_UNITS_CATEGORIES = ["number"]; diff --git a/packages/unit-conversion/src/index.ts b/packages/unit-conversion/src/index.ts index d0f7de0..30a5034 100644 --- a/packages/unit-conversion/src/index.ts +++ b/packages/unit-conversion/src/index.ts @@ -3,6 +3,7 @@ export { LABELS } from "./constants/labels"; export type { ALL_UNIT_CATEGORIES, AllUnits, + ForceUnits, LengthUnits, NumberUnits, TemperatureUnits, diff --git a/packages/unit-conversion/src/utils/common.ts b/packages/unit-conversion/src/utils/common.ts index 0c100d8..89a34bf 100644 --- a/packages/unit-conversion/src/utils/common.ts +++ b/packages/unit-conversion/src/utils/common.ts @@ -30,6 +30,7 @@ export function getUnitCategory(unit: AllUnits): keyof typeof CONVERSION_FACTORS if (isUnitInCategory(unit, "pressure")) return "pressure"; if (isUnitInCategory(unit, "energy")) return "energy"; if (isUnitInCategory(unit, "angle")) return "angle"; + if (isUnitInCategory(unit, "force")) return "force"; throw new Error(`Unknown unit: ${unit}`); } diff --git a/packages/unit-conversion/src/utils/conversion-factors.ts b/packages/unit-conversion/src/utils/conversion-factors.ts index 02cd716..5a80282 100644 --- a/packages/unit-conversion/src/utils/conversion-factors.ts +++ b/packages/unit-conversion/src/utils/conversion-factors.ts @@ -51,6 +51,7 @@ interface ConversionFactorGroups { * @property {Object} weight - Weight conversions with gram as base unit * @property {Object} volume - Volume conversions with liter as base unit * @property {Object} time - Time conversions with second as base unit + * @property {Object} force - Force conversions with Newton as base unit */ export const CONVERSION_FACTORS: ConversionFactorGroups = { // Temperature (base: Kelvin) @@ -387,4 +388,29 @@ export const CONVERSION_FACTORS: ConversionFactorGroups = { }, }, // Angle (base: radian) + + // Force (base: newton) + force: { + newton: { + isBaseUnit: true, + toBase: (v: number) => v, + fromBase: (v: number) => v, + }, + dyne: { + toBase: (v: number) => v * 1e-5, + fromBase: (v: number) => v / 1e-5, + }, + poundal: { + toBase: (v: number) => v * 0.138255, + fromBase: (v: number) => v / 0.138255, + }, + "pound-force": { + toBase: (v: number) => v * 4.44822, + fromBase: (v: number) => v / 4.44822, + }, + "kilogram-force": { + toBase: (v: number) => v / 0.1019716213, + fromBase: (v: number) => v * 0.1019716213, + }, + }, }; diff --git a/packages/unit-conversion/tests/conversion.spec.ts b/packages/unit-conversion/tests/conversion.spec.ts index d933c44..d13b928 100644 --- a/packages/unit-conversion/tests/conversion.spec.ts +++ b/packages/unit-conversion/tests/conversion.spec.ts @@ -1,6 +1,5 @@ import { describe, expect, test } from "vitest"; -import type { AllUnits } from "../src"; -import { Conversion } from "../src/main"; +import { type AllUnits, Conversion } from "../src"; type TestValues = { value: number; @@ -474,3 +473,35 @@ describe("Test energy conversions", () => { }); }); }); + +describe("Test force conversions", () => { + const forceTests: Array = [ + { value: 1, from: "newton", to: "pound-force", expected: "0.2248", unit: "lbf" }, + { value: 1, from: "newton", to: "kilogram-force", expected: "0.1019", unit: "kgf" }, + { value: 1, from: "newton", to: "dyne", expected: "100000", unit: "dyn" }, + { value: 1, from: "newton", to: "poundal", expected: "7.2330", unit: "pdl" }, + { value: 1, from: "dyne", to: "newton", expected: "0.00001", unit: "N" }, + { value: 1, from: "dyne", to: "pound-force", expected: "0", unit: "lbf" }, + { value: 1, from: "dyne", to: "kilogram-force", expected: "0", unit: "kgf" }, + { value: 1, from: "dyne", to: "poundal", expected: "0.00001", unit: "pdl" }, + { value: 1, from: "poundal", to: "newton", expected: "0.1383", unit: "N" }, + { value: 1, from: "poundal", to: "dyne", expected: "13825.5", unit: "dyn" }, + { value: 1, from: "poundal", to: "pound-force", expected: "0.03108", unit: "lbf" }, + { value: 1, from: "poundal", to: "kilogram-force", expected: "0.01409", unit: "kgf" }, + { value: 1, from: "pound-force", to: "newton", expected: "4.4482", unit: "N" }, + { value: 1, from: "pound-force", to: "kilogram-force", expected: "0.4536", unit: "kgf" }, + { value: 1, from: "kilogram-force", to: "newton", expected: "9.8066", unit: "N" }, + { value: 1, from: "kilogram-force", to: "pound-force", expected: "2.2046", unit: "lbf" }, + ]; + const convert = new Conversion({ + decimals: 4, + }); + + forceTests.forEach(({ value, from, to, expected, unit }) => { + test(`Converts ${value} ${from} to ${to}`, () => { + const result = convert.value(value).from(from).to(to); + expect(isApproximatelyEqual(+result.value, +expected)).toBe(true); + expect(result.unit).toBe(unit); + }); + }); +});