Skip to content

Commit

Permalink
add container
Browse files Browse the repository at this point in the history
  • Loading branch information
tizayi committed Aug 17, 2023
1 parent 6bc0bbb commit 262fa2a
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 148 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules/
5 changes: 5 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ module.exports = {
{ allowConstantExport: true },
],
},
settings: {
react: {
version: "detect",
}
}
};
7 changes: 5 additions & 2 deletions .github/workflows/code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ jobs:
fetch-depth: 0

- name: Install
run: npm ci
run: npm install

- name: Unit Tests
run: npm run test

- name: lint
run: npm run lint

- name: Prettier
run: npx prettier --check './src/'
run: npx prettier --check './src/'
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM registry.hub.docker.com/library/node:18-alpine as base

ENV APP_DIR /dedi-web

COPY . ${APP_DIR}
WORKDIR ${APP_DIR}

RUN npm install
RUN npm run build

CMD ["npm", "run", "preview"]
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
# Dedi-web

A browser tool to calculate the beam centering parameters. Like dedi within dawn science.
[![dedi-web code CI](https://github.com/tizayi/dedi-web/actions/workflows/code.yml/badge.svg)](https://github.com/tizayi/dedi-web/actions/workflows/code.yml)

A browser tool to calculate the beam centering parameters. Like dedi within dawn science. Built using react and vite.

## Start dev server

Start up

```bash
cd dedi-web
npm run dev
```

Start up in a container

```bash
cd dedi-web
docker build -t dedi-web .
docker run -d dedi-web
```

## Test

Run tests with vitest

```bash
cd dedi-web
npm run test
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
"vite": "^4.4.5",
"vitest": "^0.34.1"
}
}
}
232 changes: 140 additions & 92 deletions src/calculations/ray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,148 @@ import Vector2D from "./vector";
import NumericRange from "./numericRange";

export class Ray {
direction: Vector2D;
initial_point: Vector2D;
constructor(direction: Vector2D, initial_point: Vector2D) {
if (direction.length() == 0)
throw TypeError(
"The direction vector of a ray cannot be the zero vector.",
);
this.direction = direction;
this.initial_point = initial_point;
direction: Vector2D;
initial_point: Vector2D;
constructor(direction: Vector2D, initial_point: Vector2D) {
if (direction.length() == 0)
throw TypeError(
"The direction vector of a ray cannot be the zero vector.",
);
this.direction = direction;
this.initial_point = initial_point;
}

getPoint(scalar: number): Vector2D | null {
if (scalar < 0) return null;
const result = new Vector2D(this.direction.x, this.direction.y);
result.scale(scalar);
result.add(this.initial_point);
return result;
}

getPointAtDistance(distance: number): Vector2D | null {
return this.getPoint(distance / this.direction.length());
}

getParameterRange(t1: number, t2: number): NumericRange | null {
if (t1 < 0 && t2 < 0) return null;

let tMin = Math.min(t1, t2);
const tMax = Math.max(t1, t2);

if (tMin < 0) tMin = 0;

return new NumericRange(tMin, tMax);
}

private getConicIntersectionParameterRange(
coeffOfx2: number,
coeffOfxy: number,
coeffOfy2: number,
coeffOfx: number,
coeffOfy: number,
constant: number,
) {
let t1: number;
let t2: number;

const a =
coeffOfx2 * Math.pow(this.direction.x, 2) +
coeffOfxy * this.direction.x * this.direction.y +
coeffOfy2 * Math.pow(this.direction.y, 2);
const b =
2 * coeffOfx2 * this.direction.x * this.initial_point.x +
coeffOfxy *
(this.direction.x * this.initial_point.y +
this.direction.y * this.initial_point.x) +
2 * coeffOfy2 * this.direction.y * this.initial_point.y +
coeffOfx * this.direction.x +
coeffOfy * this.direction.y;
const c =
coeffOfx2 * Math.pow(this.initial_point.x, 2) +
coeffOfxy * this.initial_point.x * this.initial_point.y +
coeffOfy2 * Math.pow(this.initial_point.y, 2) +
coeffOfx * this.initial_point.x +
coeffOfy * this.initial_point.y +
constant;

const discriminant = Math.pow(b, 2) - 4 * a * c;
if (discriminant < 0) return null;
if (a == 0) {
if (b == 0)
return c == 0 ? new NumericRange(0, Number.POSITIVE_INFINITY) : null;
t1 = -c / b;
t2 = -c / b;
} else {
t1 = (0.5 * (-b - Math.sqrt(discriminant))) / a;
t2 = (0.5 * (-b + Math.sqrt(discriminant))) / a;
}

getPoint(scalar: number): Vector2D | null {
if (scalar < 0) return null;
const result = new Vector2D(this.direction.x, this.direction.y);
result.scale(scalar);
result.add(this.initial_point);
return result;
}

getPointAtDistance(distance: number): Vector2D | null {
return this.getPoint(distance / this.direction.length());
return this.getParameterRange(t1, t2);
}

private getEllipseIntersectionParameterRange(
a: number,
b: number,
centre: Vector2D,
) {
const coeffOfx2 = 1 / Math.pow(a, 2);
const coeffOfy2 = 1 / Math.pow(b, 2);
const coeffOfx = (-2 * centre.x) / Math.pow(a, 2);
const coeffOfy = (-2 * centre.y) / Math.pow(b, 2);
const constant =
Math.pow(centre.x, 2) / Math.pow(a, 2) +
Math.pow(centre.y, 2) / Math.pow(b, 2) -
1;

return this.getConicIntersectionParameterRange(
coeffOfx2,
0,
coeffOfy2,
coeffOfx,
coeffOfy,
constant,
);
}

public getCircleIntersectionParameterRange(radius: number, centre: Vector2D) {
return this.getEllipseIntersectionParameterRange(radius, radius, centre);
}

public getRectangleIntersectionParameterRange(
topLeftCorner: Vector2D,
width: number,
height: number,
): NumericRange | null {
let result: NumericRange | null;

const xmax = topLeftCorner.x + width;
const xmin = topLeftCorner.x;
const ymax = topLeftCorner.y;
const ymin = topLeftCorner.y - height;

if (this.direction.x === 0) {
if (!new NumericRange(xmin, xmax).containsValue(this.initial_point.x))
return null;
result = new NumericRange(0, Number.POSITIVE_INFINITY);
} else
result = new NumericRange(
(xmin - this.initial_point.x) / this.direction.x,
(xmax - this.initial_point.x) / this.direction.x,
);

if (this.direction.y == 0) {
if (!new NumericRange(ymin, ymax).containsValue(this.initial_point.y))
return null;
return this.getParameterRange(result.min, result.max);
}

getParameterRange(t1: number, t2: number): NumericRange | null {
if (t1 < 0 && t2 < 0) return null;

let tMin = Math.min(t1, t2);
const tMax = Math.max(t1, t2);

if (tMin < 0) tMin = 0;

return new NumericRange(tMin, tMax);
}

private getConicIntersectionParameterRange(coeffOfx2: number, coeffOfxy: number, coeffOfy2: number, coeffOfx: number, coeffOfy: number, constant: number) {
let t1: number;
let t2: number;

const a = coeffOfx2 * Math.pow(this.direction.x, 2) + coeffOfxy * this.direction.x * this.direction.y +
coeffOfy2 * Math.pow(this.direction.y, 2);
const b = 2 * coeffOfx2 * this.direction.x * this.initial_point.x + coeffOfxy * (this.direction.x * this.initial_point.y + this.direction.y * this.initial_point.x) +
2 * coeffOfy2 * this.direction.y * this.initial_point.y + coeffOfx * this.direction.x + coeffOfy * this.direction.y;
const c = coeffOfx2 * Math.pow(this.initial_point.x, 2) + coeffOfxy * this.initial_point.x * this.initial_point.y + coeffOfy2 * Math.pow(this.initial_point.y, 2) +
coeffOfx * this.initial_point.x + coeffOfy * this.initial_point.y + constant;

const discriminant = Math.pow(b, 2) - 4 * a * c;
if (discriminant < 0) return null;
if (a == 0) {
if (b == 0) return (c == 0) ? new NumericRange(0, Number.POSITIVE_INFINITY) : null;
t1 = -c / b;
t2 = -c / b;
} else {
t1 = 0.5 * (-b - Math.sqrt(discriminant)) / a;
t2 = 0.5 * (-b + Math.sqrt(discriminant)) / a;
}
return this.getParameterRange(t1, t2);
}

private getEllipseIntersectionParameterRange(a: number, b: number, centre: Vector2D) {
const coeffOfx2 = 1 / Math.pow(a, 2);
const coeffOfy2 = 1 / Math.pow(b, 2);
const coeffOfx = -2 * centre.x / Math.pow(a, 2);
const coeffOfy = -2 * centre.y / Math.pow(b, 2);
const constant = Math.pow(centre.x, 2) / Math.pow(a, 2) + Math.pow(centre.y, 2) / Math.pow(b, 2) - 1;

return this.getConicIntersectionParameterRange(coeffOfx2, 0, coeffOfy2, coeffOfx, coeffOfy, constant);
}

public getCircleIntersectionParameterRange(radius: number, centre: Vector2D) {
return this.getEllipseIntersectionParameterRange(radius, radius, centre);
}

public getRectangleIntersectionParameterRange(topLeftCorner: Vector2D, width: number, height: number): NumericRange | null {
let result: NumericRange | null;

const xmax = topLeftCorner.x + width;
const xmin = topLeftCorner.x;
const ymax = topLeftCorner.y;
const ymin = topLeftCorner.y - height;

if (this.direction.x === 0) {
if (!new NumericRange(xmin, xmax).containsValue(this.initial_point.x)) return null;
result = new NumericRange(0, Number.POSITIVE_INFINITY);
} else
result = new NumericRange((xmin - this.initial_point.x) / this.direction.x, (xmax - this.initial_point.x) / this.direction.x);

if (this.direction.y == 0) {
if (!new NumericRange(ymin, ymax).containsValue(this.initial_point.y)) return null;
return this.getParameterRange(result.min, result.max);
}

result = result.intersect(new NumericRange((ymin - this.initial_point.y) / this.direction.y, (ymax - this.initial_point.y) / this.direction.y));

return this.getParameterRange(result!.min, result!.max);
}
result = result.intersect(
new NumericRange(
(ymin - this.initial_point.y) / this.direction.y,
(ymax - this.initial_point.y) / this.direction.y,
),
);

return this.getParameterRange(result!.min, result!.max);
}
}
29 changes: 14 additions & 15 deletions src/calculations/vector.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { expect, test } from "vitest";
import Vector2D from "./vector";

test("Vector inplace addition", () => {
const vector1 = new Vector2D(1, 1);
const vector2 = new Vector2D(1, 1);
vector1.add(vector2);
expect(vector1.equals(new Vector2D(2, 2)));
});

test('Vector inplace addition', () => {
const vector1 = new Vector2D(1, 1)
const vector2 = new Vector2D(1, 1)
vector1.add(vector2)
expect(vector1.equals(new Vector2D(2, 2)))
})

test('Vector scale addition', () => {
const vector1 = new Vector2D(2, 3)
vector1.scale(2)
expect(vector1.equals(new Vector2D(4, 6)))
})
test("Vector scale addition", () => {
const vector1 = new Vector2D(2, 3);
vector1.scale(2);
expect(vector1.equals(new Vector2D(4, 6)));
});

test("Vector length", () => {
const vector1 = new Vector2D(2, 2)
expect(vector1.length()).toBe(2.8284271247461903);
})
const vector1 = new Vector2D(2, 2);
expect(vector1.length()).toBe(2.8284271247461903);
});
Loading

0 comments on commit 262fa2a

Please sign in to comment.