This commit is contained in:
Ivan Zinchenko 2024-12-12 03:48:47 +03:00
parent ef220205ce
commit 761c569e4a
5 changed files with 136 additions and 11 deletions

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
# Используем официальный образ Deno
FROM denoland/deno:alpine
# Устанавливаем рабочую директорию в контейнере
WORKDIR /app
# Копируем файлы проекта в контейнер
COPY . .
# Кэшируем зависимости
RUN deno cache main.ts
# Запускаем приложение
CMD ["run", "-ENR", "main.ts"]
EXPOSE 3000

4
IVector.ts Normal file
View File

@ -0,0 +1,4 @@
export default interface IVector {
x: number;
y: number;
}

34
main.ts
View File

@ -1,20 +1,44 @@
// @deno-types="npm:@types/express"
import express, { Request, Response } from 'express';
import cors from 'cors';
import {getCollisionPoints} from "./physics.ts";
import {getCollisionPoints, linearInterpolation, parabalInterpolatePoints} from "./physics.ts";
import {changeBasis} from "./math.ts";
import IPoint from "./IPoint.ts";
const app = express();
const PORT = 3000;
// Разрешаем CORS для всех
app.use(cors());
app.get('/interpolation', (req: Request, res: Response) => {
app.get('/api/points', (req: Request, res: Response) => {
const { g, h, l, alpha } = req.query;
if (g === undefined || h === undefined || l === undefined || alpha === undefined) {
res.status(401).send("Неверные параметры");
res.status(401).send("Параметры должны быть заданы");
}
res.json(getCollisionPoints({ g, h, l, alpha }));
res.json(changeBasis(
getCollisionPoints({ g: Number(g), h: Number(h), l: Number(l), alpha: Number(alpha) }),
-Number(alpha)
));
});
app.get('/api/interpolation', (req: Request, res: Response) => {
const { g, h, l, alpha, count } = req.query;
if (g === undefined || h === undefined || l === undefined || alpha === undefined || count === undefined) {
res.status(401).send("Параметры должны быть заданы");
}
const collisionPoints = changeBasis(getCollisionPoints({ g: Number(g), h: Number(h), l: Number(l), alpha: Number(alpha) }), -Number(alpha));
const points: IPoint[] = [];
collisionPoints.forEach((point, i, array) => {
if (i === 0) {
points.push(...linearInterpolation(point, array[i+1], Number(count)));
return;
}
if (i >= array.length - 2) return;
points.push(...parabalInterpolatePoints(point, array[i+1], Number(count)));
});
res.json(points);
});
app.listen(PORT, () => {

12
math.ts Normal file
View File

@ -0,0 +1,12 @@
import IPoint from "./IPoint.ts";
function changeBasis(points: IPoint[], angle: number): IPoint[] {
return points.map(p => ({
...p,
x: p.x*Math.cos(angle) - p.y*Math.sin(angle),
y: p.x*Math.sin(angle) + p.y*Math.cos(angle),
angle: p.angle + angle
}));
}
export { changeBasis };

View File

@ -1,22 +1,92 @@
import IParams from "./IParams.ts";
import IVector from "./IVector.ts";
import IPoint from "./IPoint.ts";
function getInitialVelocity(params: IParams) {
function getV0(params: IParams) {
return Math.sqrt(2 * params.g * params.h);
}
function getCollisionPoint(params: IParams, n: number) {
return 4 * n * getInitialVelocity(params) * Math.sin(params.alpha) / params.g;
return 4 * n * getV0(params) * Math.sin(params.alpha) / params.g;
}
function getVelocity(params: IParams, n: number): IVector {
return {
x: (2*n + 1) * getV0(params) * Math.sin(params.alpha),
y: getV0(params) * Math.cos(params.alpha)
}
}
function getAngle(params: IParams, n: number) {
const velocity = getVelocity(params, n);
return velocity.y / velocity.x;
}
function getCollisionPoints(params: IParams) {
const points = [0];
const points: IPoint[] = [
{
x: 0,
y: 0,
velocity: getV0(params),
time: 0,
angle: -Math.PI / 2 + params.alpha,
}
];
let n = 0;
while (points[points.length - 1] < params.l) {
points.push(getCollisionPoint(params, ++n));
while (points[points.length - 1].x < params.l) {
n++;
points.push({
x: getCollisionPoint(params, n),
y: 0,
velocity: Math.sqrt(getVelocity(params, n).x*getVelocity(params, n).x + getVelocity(params, n).y*getVelocity(params, n).y),
angle: getAngle(params, n),
time: 0
});
}
return points;
}
export { getCollisionPoints }
function linearInterpolation(p1: IPoint, p2: IPoint, count: number) {
const points: IPoint[] = [];
const deltaX = (p2.x - p1.x) / (count - 1);
const deltaY = (p2.y - p1.y) / (count - 1);
const deltaV = (p2.velocity - p1.velocity) / (count - 1);
for (let i = 0; i < count; i++) {
const x = p1.x + i * deltaX;
const y = p1.y + i * deltaY;
const velocity = p1.velocity + i * deltaV;
points.push({ x, y, velocity, angle: p1.angle, time: 2 });
}
return points;
}
function parabalInterpolatePoints(p1: IPoint, p2: IPoint, count: number): IPoint[] {
const points: IPoint[] = [];
const a = (Math.tan(p2.angle) - Math.tan(p1.angle))/(2*(p2.x-p1.x));
const b = Math.tan(p1.angle) - 2*a*p1.x;
const c = p1.y - a*p1.x*p1.x - b*p1.x;
const y = (x: number) => a*x*x + b*x + c;
const step = (p2.x-p1.x)/(count + 1);
for (let i = 1; i <= count; i++) {
const x = step*i + p1.x;
points.push({
x: x,
y: y(x),
angle: 2*a*x + b,
time: 1,
velocity: 0
})
}
return [p1, ...points]
}
export { getCollisionPoints, parabalInterpolatePoints, linearInterpolation };