Skip to content

Commit

Permalink
impl
Browse files Browse the repository at this point in the history
  • Loading branch information
coryasilva committed Dec 31, 2023
1 parent 39b0184 commit caadd84
Show file tree
Hide file tree
Showing 5 changed files with 498 additions and 1 deletion.
98 changes: 97 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,98 @@
# roll-calc
Roll (spiral) calculator functions.

Roll calculator functions.

This module was created for calculating dimesions of materials in rolls for inventory and winding machines.

## Install

```sh
npm install roll-calc
```

## Usage

```js
import { rollSolve } from 'roll-calc';

const materialHeight = 0.06;
const innerDiameter = 18;
const outerDiameter = 60;
const length = rollSolve(materialHeight, innerDiameter, outerDiameter);

console.log(length);
//=> 42882.74547004675
```

## API

### `function rollLength(h: number, d0: number, d1: number): number`

Calculates length of a roll (2D spiral).

Equations from https://www.giangrandi.ch/soft/spiral/spiral.shtml

```js
import { rollLength } from 'roll-calc';

const materialHeight = 0.1;
const innerDiameter = 2;
const outerDiameter = 3;
const length = rollLength(materialHeight, innerDiameter, outerDiameter);

console.log(length);
//=> 39.27313461871492
```

### `function rollOuterDiameter(h: number, d0: number, l: number, maxIter?: number): number`

Calcuates the outer diameter of a roll (2D spiral).

```js
import { rollOuterDiameter } from 'roll-calc';

const materialHeight = 0.1;
const innerDiameter = 2;
const length = 39.273_134_62;
const outerDiameter = rollOuterDiameter(materialHeight, innerDiameter, length);

console.log(outerDiameter);
//=> 3.0000000000272684
```

### `function rollInnerDiameter(h: number, d1: number, l: number): number`

Calculates the inner diameter of a roll (2D spiral).

```js
import { rollInnerDiameter } from 'roll-calc';

const materialHeight = 0.1;
const outerDiameter = 3;
const length = 39.273_134_62;
const innerDiameter = rollInnerDiameter(materialHeight, innerDiameter, length);

console.log(innerDiameter);
//=> 1.999999999959101
```

### `rollMaterialHeight(d0: number, d1: number, l: number): number`

Calculates the nominal material height or thickness in a roll (2D Spiral).

Equations from:
> Thickness of Material on a Roll Winding: Machines, Mechanics and Measurements
By James K. Good, David R. Roisum
page 124

```js
import { rollMaterialHeight } from 'roll-calc';

const innerDiameter = 2;
const outerDiameter = 3;
const length = 39.273_134_62;
const materialHeight = rollMaterialHeight(innerDiameter, outerDiameter, length);

console.log(materialHeight);
//=> 0.09999178458720241
```
124 changes: 124 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
Calculates lenght of a roll (2D spiral).
Equations from https://www.giangrandi.ch/soft/spiral/spiral.shtml
@example
```
import { rollLength } from 'roll-calc';
const materialHeight = 0.1;
const innerDiameter = 2;
const outerDiameter = 3;
const length = rollLength(materialHeight, innerDiameter, outerDiameter);
console.log(length);
//=> 39.27313461871492
```
@param h - Material height (thickness); 0 < h < Infinity
@param d0 - Inner diameter; h < d0 > d1
@param d1 - Outer diameter; d0 < d1 < Infinity
@returns calculated roll length
*/
export function rollLength(h: number, d0: number, d1: number): number | undefined;

/**
Calcuates the outer diameter of a roll (2D spiral).
@example
```
import { rollOuterDiameter } from 'roll-calc';
const materialHeight = 0.1;
const innerDiameter = 2;
const length = 39.273_134_62;
const outerDiameter = rollOuterDiameter(materialHeight, innerDiameter, length);
console.log(outerDiameter);
//=> 3.0000000000272684
```
@param h - Material height (thickness); 0 < h < Infinity
@param d0 - Inner diameter; h < d0 > Infinity
@param l - Roll Length; pi * d0 <= l < Infinity
@param maxIter - Maximum number of interation for convergence of the Newton's method; default 10
@returns calculated outer diameter
*/
export function rollOuterDiameter(h: number, d0: number, l: number, maxIter?: number): number | undefined;

/**
Calculates the inner diameter of a roll (2D spiral).
@example
```
import { rollInnerDiameter } from 'roll-calc';
const materialHeight = 0.1;
const outerDiameter = 3;
const length = 39.273_134_62;
const innerDiameter = rollInnerDiameter(materialHeight, innerDiameter, length);
console.log(innerDiameter);
//=> 1.999999999959101
```
@param h - Material height (thickness); 0 < h < Infinity
@param d1 - Outer diameter; h < d1 < Infinity
@param l - Roll Length; pi * d1 <= l < Infinity
@returns calculated inner diameter
*/
export function rollInnerDiameter(h: number, d1: number, l: number): number | undefined;

/**
Calculates the nominal material height or thickness in a roll (2D Spiral).
Equations from:
Thickness of Material on a Roll Winding: Machines, Mechanics and Measurements
By James K. Good, David R. Roisum
page 124
@example
```
import { rollMaterialHeight } from 'roll-calc';
const innerDiameter = 2;
const outerDiameter = 3;
const length = 39.273_134_62;
const materialHeight = rollMaterialHeight(innerDiameter, outerDiameter, length);
console.log(materialHeight);
//=> 0.09999178458720241
```
@param d0 - Inner diameter; 0 < d0 > d1
@param d1 - Outer diameter; d0 < d1 < Infinity
@param l - Roll Length; pi * d1 <= l < Infinity
@returns calculated material height (thickness)
*/
export function rollMaterialHeight(d0: number, d1: number, l: number): number | undefined;

/**
Solves one missing dimension of a roll (2D spiral).
Pass in at least three arguments to solve for the fourth.
@example
```
import { rollSolve } from 'roll-calc';
const materialHeight = 0.06;
const innerDiameter = 18;
const outerDiameter = 60;
const length = rollSolve(materialHeight, innerDiameter, outerDiameter, undefined);
console.log(length);
//=> 42882.74547004675
```
@param h - Material height; 0 < h > Infinity
@param d0 - Inner diameter; 0 < d0 > Infinity
@param d1 - Outer diameter; 0 < d1 < Infinity
@param l - Roll Length; 0 < l < Infinity
@returns calculated material height (thickness)
*/
export function rollSolve(h?: number, d0?: number, d1?: number, l?: number): number | undefined;
138 changes: 138 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
const {sqrt, PI} = Math;
const notFinite = n => !Number.isFinite(n);

function getExactLength(phi0, phi1, h) {
let length;
length = (phi1 / 2) * sqrt((phi1 * phi1) + 1);
length += (1 / 2) * Math.log(phi1 + sqrt((phi1 * phi1) + 1));
length -= (phi0 / 2) * sqrt((phi0 * phi0) + 1);
length -= (1 / 2) * Math.log(phi0 + sqrt((phi0 * phi0) + 1));
length *= h / (2 * PI);
return length;
}

function getExactDeltaLengthDeltaPhi(phi, h) {
let delta;
const phi2 = phi * phi;
delta = ((2 * phi2) + 1) / (2 * sqrt(phi2 + 1));
delta += (phi + sqrt(phi2 + 1)) / ((2 * phi * sqrt(phi2 + 1)) + (2 * phi2) + 2);
delta *= h / (2 * PI);
return delta;
}

export function rollLength(h, d0, d1) {
if (notFinite(h)
|| notFinite(d0)
|| notFinite(d1)
|| h <= 0
|| d0 <= 0
|| d1 <= 0
|| h > d0
|| d0 >= d1
) {
return;
}

const phi0 = PI * d0 / h;
const phi1 = PI * d1 / h;
return getExactLength(phi0, phi1, h);
}

export function rollOuterDiameter(h, d0, l, maxIter = 10) {
if (notFinite(h)
|| notFinite(d0)
|| notFinite(l)
|| h <= 0
|| d0 <= 0
|| h > d0
|| l < PI * d0
) {
return;
}

/* To find "phi1" from L(phi1)=(h/2pi)(...) we have to numerically solve
* (h/2pi)(...)-L=0, so we have f(phi1)=(h/2pi)(...)-L=0
* The approximate formula is used to find a starting point, from which we
* use Newton's method to find a more accurate numerical solution as follows:
*
* phi_n+1 = phi_n - (f(phi_n)/f'(phi_n))
*
* Whith this method, there is no need to invert the function, it's only
* necessary to find it's derivative. It converges quite quickly and only a
* few iterations are required for the precision of the floating point
* variable used.
*/
const n = (h - d0 + sqrt((((d0 - h) * (d0 - h)) + (4 * h * l)) / PI)) / (2 * h);
let d1 = (2 * n * h) + d0;
const phi0 = PI * d0 / h;
let phi1 = PI * d1 / h;
let deltaPhi;
// This is the starting approximation.
for (let i = 0; i <= maxIter; i++) {
deltaPhi = (getExactLength(phi0, phi1, h) - l) / getExactDeltaLengthDeltaPhi(phi1, h);
phi1 -= deltaPhi;
// Stop looping if solution already found.
if (deltaPhi === 0) {
break;
}
}

// Now we have phi1 and we find d1.
d1 = phi1 * h / PI;
// Note we could find a more accurate n if needed with:
// n = (d1 - d0) / (2 * h);
return d1;
}

export function rollInnerDiameter(h, d1, l) {
if (notFinite(h)
|| notFinite(d1)
|| notFinite(l)
|| h <= 0
|| d1 <= h
|| l < PI * d1
) {
return;
}

const minOuterDia = rollOuterDiameter(h, h, l);
const length = rollLength(h, minOuterDia, d1);
return rollOuterDiameter(h, h, length);
}

export function rollMaterialHeight(d0, d1, l) {
if (notFinite(d0)
|| notFinite(d1)
|| notFinite(l)
|| d0 <= 0
|| d1 <= d0
|| l < PI * d1
) {
return;
}

return (PI / (4 * l)) * ((d1 ** 2) - (d0 ** 2));
}

export function rollSolve(h, d0, d1, l) {
if (h && d0 && d1 && l) {
// Nothing to solve.
return;
}

if (h && d0 && d1 && !l) {
return rollLength(h, d0, d1);
}

if (h && d0 && l && !d1) {
return rollOuterDiameter(h, d0, l);
}

if (h && d1 && l && !d0) {
return rollInnerDiameter(h, d1, l);
}

if (d0 && d1 && l && !h) {
return rollMaterialHeight(d0, d1, l);
}
}
Loading

0 comments on commit caadd84

Please sign in to comment.