From 761c569e4a8165c902784c73cd185bcc01099a6b Mon Sep 17 00:00:00 2001 From: Ivan Zinchenko Date: Thu, 12 Dec 2024 03:48:47 +0300 Subject: [PATCH] wip rip --- Dockerfile | 15 ++++++++++ IVector.ts | 4 +++ main.ts | 34 ++++++++++++++++++---- math.ts | 12 ++++++++ physics.ts | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 Dockerfile create mode 100644 IVector.ts create mode 100644 math.ts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7ab4627 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +# Используем официальный образ Deno +FROM denoland/deno:alpine + +# Устанавливаем рабочую директорию в контейнере +WORKDIR /app + +# Копируем файлы проекта в контейнер +COPY . . + +# Кэшируем зависимости +RUN deno cache main.ts + +# Запускаем приложение +CMD ["run", "-ENR", "main.ts"] +EXPOSE 3000 \ No newline at end of file diff --git a/IVector.ts b/IVector.ts new file mode 100644 index 0000000..5e44d09 --- /dev/null +++ b/IVector.ts @@ -0,0 +1,4 @@ +export default interface IVector { + x: number; + y: number; +} \ No newline at end of file diff --git a/main.ts b/main.ts index c312fe5..29deaa3 100644 --- a/main.ts +++ b/main.ts @@ -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, () => { diff --git a/math.ts b/math.ts new file mode 100644 index 0000000..9e678bc --- /dev/null +++ b/math.ts @@ -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 }; \ No newline at end of file diff --git a/physics.ts b/physics.ts index 22cce64..75222b5 100644 --- a/physics.ts +++ b/physics.ts @@ -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 } \ No newline at end of file +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 }; \ No newline at end of file