From 6d7c43c85f8852ed3b3fa9cefc742bc87e941842 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 17 Dec 2025 12:12:16 +0100 Subject: =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D1=82=D1=8C=D1=8E=20=D0=B3=D0=BB=D0=B0=D0=B2=D1=83?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../3/5_ideal_gas/geometry.pas" | 344 +++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" (limited to 'Занимательное программирование/3/5_ideal_gas/geometry.pas') diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" new file mode 100644 index 0000000..cbbff5d --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" @@ -0,0 +1,344 @@ +unit Geometry; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils; + +type + { Вершины } + Vertex = record + x, y, z: Real; { Координаты вершины } + end; + { Ребра } + Edge = record + src, dest: Integer; { Индексы соединяемых вершин } + end; + + Object3D = class + public + vertices: array of Vertex; { вершины } + edges: array of Edge; { ребра } + xc, yc, zc: Real; { координаты центра объекта } + vx, vy, vz: Real; { значения составляющих его скорости } + xa, ya, za: Real; { скорость вращения вокруг оси } + + constructor Create(var center, velocity, axis: Vertex); + + procedure MoveCenter(); + end; + + Matrix = array[1..4, 1..4] of Real; { матрица 4x4 } + Column = array[1..4] of Real; { столбец } + +function CopyObject3D(Shape: Object3D): Object3D; + +{ умножение матрицы на матрицу } +function MMMult(lhs, rhs: Matrix): Matrix; +{ умножение матрицы на столбец } +function MCMult(lhs: Matrix; rhs: Column): Column; +{ матрица поворота модели } +function RotateMatrix(xa, ya, za: Real): Matrix; +function MoveMatrix(tx, ty, tz: Real): Matrix; +function ResizeMatrix(sx, sy, sz: Real): Matrix; +procedure RotateShape(Shape: Object3D); +procedure MoveShape(Shape: Object3D; Width, Height: Real); +procedure ResizeShape(var Shape: Object3D; sx, sy, sz: Real); + +implementation + +constructor Object3D.Create(var center, velocity, axis: Vertex); +const + size = 10; + cubeVertices: array of Vertex = ( + (x: -size; y: -size; z: -size), + (x: -size; y: size; z: -size), + (x: size; y: size; z: -size), + (x: size; y: -size; z: -size), + (x: -size; y: -size; z: size), + (x: -size; y: size; z: size), + (x: size; y: size; z: size), + (x: size; y: -size; z: size) + ); + cubeEdges: array of Edge = ( + (src: 0; dest: 1), + (src: 1; dest: 2), + (src: 2; dest: 3), + (src: 3; dest: 0), + (src: 4; dest: 5), + (src: 5; dest: 6), + (src: 6; dest: 7), + (src: 7; dest: 4), + (src: 0; dest: 4), + (src: 1; dest: 5), + (src: 2; dest: 6), + (src: 3; dest: 7) + ); +begin + vertices := cubeVertices; + edges := cubeEdges; + xc := center.x; + yc := center.y; + zc := center.z; + vx := velocity.x; + vy := velocity.y; + vz := velocity.z; + xa := axis.x; + ya := axis.y; + za := axis.z +end; + +procedure Object3D.MoveCenter(); +begin + xc := xc + Vx; + yc := yc + Vy; + zc := zc + Vz +end; + +function CopyObject3D(Shape: Object3D): Object3D; +begin + CopyObject3D.vertices := Copy(Shape.vertices, 0); + CopyObject3D.edges := Copy(Shape.edges, 0); + + CopyObject3D.xc := Shape.xc; + CopyObject3D.yc := Shape.yc; + CopyObject3D.zc := Shape.zc +end; + +function MMMult(lhs, rhs: Matrix): Matrix; +var + i, j, k: Integer; + r: Matrix; + s: Real; +begin + for i := 1 to 4 do + for j := 1 to 4 do + begin + s := 0; + for k := 1 to 4 do + s := s + lhs[i, k] * rhs[k, j]; + r[i, j] := s; + end; + MMMult := r; +end; + +function MCMult(lhs: Matrix; rhs: Column): Column; +var + k, i: Integer; + s: Real; + r: Column; +begin + for i := 1 to 4 do { аналогично MMMult } + begin + s := 0; + + for k := 1 to 4 do + s := s + lhs[i, k] * rhs[k]; + r[i] := s; + end; + + MCMult := r; +end; + +function RotateMatrix(xa, ya, za: Real): Matrix; +var + xr, yr, zr: Matrix; +begin + { матрица поворота вокруг оси Ox } + xr[1, 1] := 1; + xr[1, 2] := 0; + xr[1, 3] := 0; + xr[1, 4] := 0; + + xr[2, 1] := 0; + xr[2, 2] := Cos(xa); + xr[2, 3] := -Sin(xa); + xr[2, 4] := 0; + + xr[3, 1] := 0; + xr[3, 2] := Sin(xa); + xr[3, 3] := Cos(xa); + xr[3, 4] := 0; + + xr[4, 1] := 0; + xr[4, 2] := 0; + xr[4, 3] := 0; + xr[4, 4] := 1; + + { матрица поворота вокруг оси Oy } + yr[1, 1] := Cos(ya); + yr[1, 2] := 0; + yr[1, 3] := Sin(ya); + yr[1, 4] := 0; + + yr[2, 1] := 0; + yr[2, 2] := 1; + yr[2, 3] := 0; + yr[2, 4] := 0; + + yr[3, 1] := -Sin(ya); + yr[3, 2] := 0; + yr[3, 3] := Cos(ya); + yr[3, 4] := 0; + + yr[4, 1] := 0; + yr[4, 2] := 0; + yr[4, 3] := 0; + yr[4, 4] := 1; + + { матрица поворота вокруг оси Oz } + zr[1, 1] := Cos(za); + zr[1, 2] := -Sin(za); + zr[1, 3] := 0; + zr[1, 4] := 0; + + zr[2, 1] := Sin(za); + zr[2, 2] := Cos(za); + zr[2, 3] := 0; + zr[2, 4] := 0; + + zr[3, 1] := 0; + zr[3, 2] := 0; + zr[3, 3] := 1; + zr[3, 4] := 0; + + zr[4, 1] := 0; + zr[4, 2] := 0; + zr[4, 3] := 0; + zr[4, 4] := 1; + + RotateMatrix := MMMult(MMMult(xr, yr), zr) +end; + +function MoveMatrix(tx, ty, tz: Real): Matrix; +begin + MoveMatrix[1, 1] := 1; + MoveMatrix[1, 2] := 0; + MoveMatrix[1, 3] := 0; + MoveMatrix[1, 4] := tx; + + MoveMatrix[2, 1] := 0; + MoveMatrix[2, 2] := 1; + MoveMatrix[2, 3] := 0; + MoveMatrix[2, 4] := ty; + + MoveMatrix[3, 1] := 0; + MoveMatrix[3, 2] := 0; + MoveMatrix[3, 3] := 1; + MoveMatrix[3, 4] := tz; + + MoveMatrix[4, 1] := 0; + MoveMatrix[4, 2] := 0; + MoveMatrix[4, 3] := 0; + MoveMatrix[4, 4] := 1 +end; + +function ResizeMatrix(sx, sy, sz: Real): Matrix; +begin + ResizeMatrix[1, 1] := sx; + ResizeMatrix[1, 2] := 0; + ResizeMatrix[1, 3] := 0; + ResizeMatrix[1, 4] := 0; + + ResizeMatrix[2, 1] := 0; + ResizeMatrix[2, 2] := sy; + ResizeMatrix[2, 3] := 0; + ResizeMatrix[2, 4] := 0; + + ResizeMatrix[3, 1] := 0; + ResizeMatrix[3, 2] := 0; + ResizeMatrix[3, 3] := sz; + ResizeMatrix[3, 4] := 0; + + ResizeMatrix[4, 1] := 0; + ResizeMatrix[4, 2] := 0; + ResizeMatrix[4, 3] := 0; + ResizeMatrix[4, 4] := 1 +end; + +procedure RotateShape(Shape: Object3D); +var + rm: Matrix; + i: Integer; + c: Column; +begin + rm := RotateMatrix(Shape.xa, Shape.ya, Shape.za); { сгенерировать матрицу вращения } + c[4] := 1; { последний элемент столбца всегда равен единице } + + for i := 0 to High(Shape.vertices) do { цикл по всем вершинам } + begin { High(a) возвращает верхний индекс массива a } + c[1] := Shape.vertices[i].x; { инициализация столбца } + c[2] := Shape.vertices[i].y; + c[3] := Shape.vertices[i].z; + + c := MCMult(rm, c); { вызов преобразования } + + Shape.vertices[i].x := c[1]; { внесение изменений в модель } + Shape.vertices[i].y := c[2]; { в соответствии с полученным } + Shape.vertices[i].z := c[3] { результатом преобразования } + end +end; + +procedure MoveShape(Shape: Object3D; Width, Height: Real); +begin + if Shape.xc > Width then + begin + Shape.xc := Width; + Shape.Vx := -Shape.Vx + end; + if Shape.xc < -Width then + begin + Shape.xc := -Width; + Shape.Vx := -Shape.Vx + end; + + if Shape.yc > Height then + begin + Shape.yc := Height; + Shape.Vy := -Shape.Vy + end; + if Shape.yc < -Height then + begin + Shape.yc := -Height; + Shape.Vy := -Shape.Vy + end; + + if Shape.zc > 500 then + begin + Shape.zc := 500; + Shape.Vz := -Shape.Vz + end; + if Shape.zc < 200 then + begin + Shape.zc := 200; + Shape.Vz := -Shape.Vz + end; +end; + +procedure ResizeShape(var Shape: Object3D; sx, sy, sz: Real); +var + mm: Matrix; + i: Integer; + c: Column; +begin + mm := ResizeMatrix(sx, sy, sz); + c[4] := 1; + + for i := 0 to High(Shape.vertices) do + begin + c[1] := Shape.vertices[i].x; + c[2] := Shape.vertices[i].y; + c[3] := Shape.vertices[i].z; + + c := MCMult(mm, c); + + Shape.vertices[i].x := c[1]; + Shape.vertices[i].y := c[2]; + Shape.vertices[i].z := c[3] + end +end; + +end. + -- cgit v1.2.3