Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289

Построение перспективной проекции трехмерного объекта

16.03.2020, 15:01. Показов 2469. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Построить перспективную проекцию фигуры
(0;0;0) (0;120;0); (90;0;0) (0;120;0); (0;0;90) (0;120;0);
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.03.2020, 15:01
Ответы с готовыми решениями:

Построение ортогональной проекции модели трехмерного объекта
Построить ортогональную проекцию модели трехмерного объекта (Правильная усеченная 3-х угольная пирамида, боковые ребра равны стороне...

Реализация перспективной проекции квадрата с помощью glFrustum
День добрый! Мне нужно реализовать перспективную проекцию обычного квадрата (чтобы при изменении координаты отрисовки Z менялся размер...

Построение трехмерного объекта и анимация поворота
Построить четырехугольную пирамиду. Поворот: (относительно оси Оz) Пример: Поворот куба относительно оси Ox. uses...

12
Почетный модератор
 Аватар для Puporev
64315 / 47611 / 32743
Регистрация: 18.05.2008
Сообщений: 115,167
16.03.2020, 15:58
А что у Вас 3 точки (0;120;0) дублируются?

Добавлено через 4 минуты
И вообще какой-то бардак с точками, уточните.
0
Модератор
4141 / 2353 / 811
Регистрация: 15.11.2015
Сообщений: 9,410
16.03.2020, 16:46
Какая-то метёлка получается, ещё и 2 пары отрезков одинаковые.
0
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289
16.03.2020, 19:34  [ТС]
Puporev, (0;0;0); (0;50;0); (50;0;0); (50;50;0); (50;0;50); (50;50;50); (0;0;50); (0;50;50);
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
16.03.2020, 23:35
Спроецировать точки объекта на плоскость центральной проекцией? Или трансформировать точки объекта матрицей преобразований?
Кстати на плоскости две точки схода, в 3D уже три точки схода.
0
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289
17.03.2020, 20:01  [ТС]
GoodWeather, Центральной проекцией
0
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289
19.03.2020, 20:02  [ТС]
(0;0;0); (0;50;0); (50;0;0); (50;50;0); (50;0;50); (50;50;50); (0;0;50); (0;50;50);
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
20.03.2020, 22:59
Есть некоторая точка S - центр проекции (или точка зрения/схода). И есть некоторая плоскость P - та на которую проецируется.
Эти данные нужно как-то задать, либо вручную, либо дать возможность пользователю.

Далее требуется вычислить прямые, проходящие через точку S и все точки фигуры (проецирующие лучи).
После, требуется выяснить в какой точке данные прямые пересекают плоскость P.
Далее нужно преобразовать координаты данных точек из трёхмерных в двухмерные (локально на плоскости P).
Это и будут искомые точки.

Общее уравнение плоскости: A * X + B * Y + C * Z + D = 0.
А вот уравнения прямой в пространстве в общем виде, насколько я помню, нету.

Есть в виде системы двух уравнений, пересекающихся плоскостей. Это нам не особо подходит.
Есть в виде системы трёх параметрических уравнений. Нам ещё неудобнее.
И есть в виде канонических уравнений: которое по сути разделяется на две составляющие - точка на прямой и направляющий вектор.

Точка же у нас уже есть, и она для всех прямых одинаковая. Останется получить координаты направляющих векторов.
Надо загуглить формулы...

Добавлено через 3 часа 15 минут
Итак. Получить направляющий вектор проще простого. Надо из координат точки объекта вычесть координаты точки схода.
Технически, мы типа делаем обычный перенос, таким образом чтоб точка схода совпала с началом координат.

Чтобы найти точку пересечения прямой с плоскостью, мы должны преобразовать нашу запись канонических уравнений в виде "точка + вектор" в параметрические уравнения и подставить их в уравнение плоскости P.
Решив получившееся выражение мы получим коэффициент параметрических уравнений, при котором прямая пересекает плоскость.
И подставив этот полученный коэффициент в эти же параметрические уравнения - получится точка на плоскости. Правда пока лишь ещё трёхмерная...

Осталось преобразование трёхмерных точек на плоскости в двухмерные точки на этой же плоскости... хмм...
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
22.03.2020, 20:35
Математика:
Параметрическим уравнением прямой в пространстве, проходящей через точку https://www.cyberforum.ru/cgi-bin/latex.cgi?M(x_{0},y_{0},z_{0}) параллельно вектору https://www.cyberforum.ru/cgi-bin/latex.cgi?V(l,m,n) называется система:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\left\{\begin{matrix}x=x_{0}+l\cdot\lambda\\y=y_{0}+m\cdot\lambda\\z=z_{0}+n\cdot\lambda\end{matrix}\right.
Каноническим уравнением прямой в пространстве, проходящей через точку https://www.cyberforum.ru/cgi-bin/latex.cgi?M(x_{0},y_{0},z_{0}) параллельно вектору https://www.cyberforum.ru/cgi-bin/latex.cgi?V(l,m,n) называется равенство:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{x-x_{0}}{l}=\frac{y-y_{0}}{m}=\frac{z-z_{0}}{n}
Параметрическое уравнение прямой и каноническое уравнение прямой могут быть получены друг из друга:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{x-x_{0}}{l}=\frac{y-y_{0}}{m}=\frac{z-z_{0}}{n}\;\;\;\Leftrightarrow\;\;\left\{\begin{matrix}x=x_{0}+l\cdot\lambda\\y=y_{0}+m\cdot\lambda\\z=z_{0}+n\cdot\lambda\end{matrix}\right.
Уравнение прямой, проходящей через точку https://www.cyberforum.ru/cgi-bin/latex.cgi?M(x_{0},y_{0},z_{0}) и перпендикулярной к плоскости https://www.cyberforum.ru/cgi-bin/latex.cgi?Ax+By+Cz+D=0 следующее:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{x-x_{0}}{A}=\frac{y-y_{0}}{B}=\frac{z-z_{0}}{C}
Уравнением прямой в пространстве, проходящей через две точки https://www.cyberforum.ru/cgi-bin/latex.cgi?M(x_{0},y_{0},z_{0}) и https://www.cyberforum.ru/cgi-bin/latex.cgi?N(x_{1},y_{1},z_{1}) называется равенство:

https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{x-x_{0}}{x_{1}-x_{0}}=\frac{y-y_{0}}{y_{1}-y_{0}}=\frac{z-z_{0}}{z_{1}-z_{0}}
Код:
Опишем типы данных:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
Type
  TPoint3F = Record
    X: Double;
    Y: Double;
    Z: Double;
  End;
  TPlane3F = Record
    A: Double;
    B: Double;
    C: Double;
    D: Double;
  End;
Объявим константу:
Delphi
1
2
Const
  FIGURE_TEST: Array [0 .. 7] Of TPoint3F = ((X: 0; Y: 0; Z: 0), (X: 0; Y: 50; Z: 0), (X: 50; Y: 0; Z: 0), (X: 50; Y: 50; Z: 0), (X: 50; Y: 0; Z: 50), (X: 50; Y: 50; Z: 50), (X: 0; Y: 0; Z: 50), (X: 0; Y: 50; Z: 50));
Основные функции вот такие:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Function GetPlaneIntersectionPoint(Const Plane: TPlane3F; Const LinePoint: TPoint3F; Const LineVector: TPoint3F): TPoint3F;
Var
  Denominator: Double;
  Coefficient: Double;
Begin
Denominator := (Plane.A * LineVector.X + Plane.B * LineVector.Y + Plane.C * LineVector.Z);
If (Denominator <> 0) Then
  Coefficient := -((Plane.A * LinePoint.X + Plane.B * LinePoint.Y + Plane.C * LinePoint.Z + Plane.D) / Denominator)
Else
  Coefficient := 0;
Result.X := LinePoint.X + LineVector.X * Coefficient;
Result.Y := LinePoint.Y + LineVector.Y * Coefficient;
Result.Z := LinePoint.Z + LineVector.Z * Coefficient;
End;
 
Function GetPlanePerpendicularPoint(Const Plane: TPlane3F; Const Point: TPoint3F): TPoint3F;
Var
  Vector: TPoint3F;
Begin
Vector.X := Plane.A;
Vector.Y := Plane.B;
Vector.Z := Plane.C;
Result := GetPlaneIntersectionPoint(Plane, Point, Vector);
End;
 
Function GetLineVector(Const BasePoint: TPoint3F; Const EndPoint: TPoint3F): TPoint3F;
Begin
Result.X := EndPoint.X - BasePoint.X;
Result.Y := EndPoint.Y - BasePoint.Y;
Result.Z := EndPoint.Z - BasePoint.Z;
End;
 
Function GetCentralProjection(Const RealPoint: TPoint3F; Const CenterOfProjection: TPoint3F; Const ProjectionPlane: TPlane3F): TPoint3F;
Var
  Vector: TPoint3F;
Begin
Vector := GetLineVector(CenterOfProjection, RealPoint);
Result := GetPlaneIntersectionPoint(ProjectionPlane, CenterOfProjection, Vector);
End;
Только не проверял ошибку вида "прямая лежит в плоскости или параллельна ей"...

А вот как преобразовать плоскость (вернее точки на ней) в пространстве {X,Y,Z} в просто плоскость {X,Y} - пока чёт не сообразил.
Так-то по идее обычной матрицей преобразований можно - но как вот коэффициенты высчитать без мороки?
0
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289
23.03.2020, 11:17  [ТС]
GoodWeather, при запуске пустая форма появляется
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
23.03.2020, 13:39
Я накорябал основные функции для выполнения операции проецирования точки. Кроме вида относительно плоскости.

Задавать параметры, преобразовывать фигуры и что-то где-то рисовать - это ж уже отдельно делается.

Какие должны быть параметры проецирования? Как и где должно быть нарисовано? В каком(их) ракурсе(ах)?

Добавлено через 1 минуту
Свою фигуру вы как рисуете?
0
Модератор
4141 / 2353 / 811
Регистрация: 15.11.2015
Сообщений: 9,410
23.03.2020, 13:48
Давным-давно я по простому сделал перспективу:
Delphi
1
2
3
4
5
6
7
8
9
10
var
  f: extended;
...
  f := 1000; // Дальность схождения координат. Подберите значение, которое больше устраивает.
...
procedure perspect(var x, y, z: extended);
begin
  x := f*x/(f-z);
  y := f*y/(f-z);
end;
Потом фигуры отображаются по координатам x и y.
0
0 / 0 / 0
Регистрация: 26.11.2017
Сообщений: 289
27.03.2020, 09:38  [ТС]
AzAtom, indeclared indefiner figure, vertexes,ribs, но в type они объявлены и не понятно как определить существующие рёбра
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
 
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
 const VertexCount=8;
 const ViewDist=200;
 
type
TFigure = record
Vertexes: array[0..VertexCount - 1] of record
X, Y, Z: Double;
end;
Ribs: array[0..VertexCount - 1, 0..VertexCount - 1] of Boolean;
PrVertexes: array[0..VertexCount - 1] of record
prX, prY: Integer;
end;
end;
 
procedure ProjectFigure(var F: TFigure);//расчет координат проекции
var
I: Integer;
P: Double;
maxX, maxY:integer;
begin
maxX:=round(form1.Width/2);
maxY:=round(form1.Height/2);
for I := 0 to VertexCount - 1 do
with F.Vertexes[I], F.PrVertexes[I] do
begin
P:=z+ViewDist;
prX := maxX + Round(x * ViewDist/p);
prY := maxY + Round(y * ViewDist/p);
end;
 
 
 end;
procedure DrawProjection(F: TFigure); var I, J: Integer; //отрисовка проекции фигуры
  begin with F do for I := 0 to VertexCount - 2 do for J := I + 1 to VertexCount - 1 do
  if Ribs[I, J] then
  begin form1.Canvas.MoveTo(PrVertexes[I].prX, PrVertexes[I].prY);
  form1.Canvas.LineTo(PrVertexes[j].prX, PrVertexes[j].prY);
   end;
end;
 
 
procedure InitFigure; //инициальзация фигуры
 
  begin
    with Figure do
  begin
   Vertexes[0].x := 0;
   Vertexes[0].y := 0;
   Vertexes[0].z := 0;
   Vertexes[1].x := 0;
   Vertexes[1].y := 50;
   Vertexes[1].z := 0;
   Vertexes[2].x := 50;
   Vertexes[2].y := 0;
   Vertexes[2].z := 0;
   Vertexes[3].x := 50;
   Vertexes[3].y := 50;
   Vertexes[3].z := 0;
   Vertexes[4].x := 50;
   Vertexes[4].y := 0;
   Vertexes[4].z := 50;
   Vertexes[5].x := 50;
   Vertexes[5].y := 50;
   Vertexes[5].z := 50;
   Vertexes[6].x := 0;
   Vertexes[6].y := 0;
   Vertexes[6].z := 50;
   Vertexes[7].x := 0;
   Vertexes[7].y := 50;
   Vertexes[7].z := 50;
 
   Ribs[i, j] := True;
 
    end;
   end;
 
 
end.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.03.2020, 09:38
Помогаю со студенческими работами здесь

Построение экранного отображения каркасной модели трехмерного объекта
помогите пожалуйста исправить ошибки в лабе Задание Лабораторная работа №5 ПОСТРОЕНИЕ ЭКРАННОГО ОТОБРАЖЕНИЯ КАРКАСНОЙ МОДЕЛИ...

Проекции трехмерного графика
Всем привет. Заранее извините, если неправильно сформулировал заголовок. Создал трехмерный график на matlab(простенький, код ниже) ...

Получить в двумерных массивах три проекции трехмерного тела
В трехмерном массиве k(l, m, n), состоящем из нулей и единиц, хранится сеточное изображение некоторого трехмерного тела. Получить в...

Построение трехмерной проекции
Здравствуйте! помогите пожалуйста разобраться, что я сделал не так, не получается конечный график как на задании.

Построение трехмерного графика
Подскажите пожалуйста почему при введение функции у меня не получается график?Вот как на рисунки и вот как у меня,где может быть ошибка


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru