Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

3D - куб   Найти похожие ветки 

 
X-Disa ©   (2004-04-25 10:26) [0]

Уважаемые мастера, как мне изобразить на плоскости (в TBitmap) куб, если известная его сторона и координаты его центра на плоскости?


 
Yar-Com   (2004-04-26 13:59) [1]

Нужен куб с произвольным углами поворота ? или статическая картинка?


 
Pa5ha   (2004-04-26 15:04) [2]

В перспективе, или ортоганальной проекции?


 
uny   (2004-04-26 15:07) [3]

а вы с примерами спрашивайте:))
(читать интереснее)


 
Yar-Com   (2004-04-26 16:00) [4]

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


 
X-Disa ©   (2004-04-27 14:45) [5]

Нет, просто статичная картинка. С углами поворота - это пока не надо. Но если есть, хорошо :)


 
LM2   (2004-04-27 15:12) [6]

Самый простой способ - рисуешь два квадрата со смещением, потом углы соединяешь прямой


 
IXT ©   (2004-04-27 19:53) [7]

Что-то я не понял - Сложно на TBitmap F1 нажать??? Или фантазия не позволяет на бумаге куб нарисовать? Потом, что значит известна одна сторона, - ее положение в пространстве?


 
Mihey ©   (2004-04-27 23:27) [8]

2 IXT:

А формулы тоже через F1 искать? Задача на математику, суть - не использовать 3d-средства.


 
Думкин ©   (2004-04-28 07:13) [9]

> X-Disa ©   (27.04.04 14:45) [5]

Все-таки, про проекцию не ответили: Pa5ha   (26.04.04 15:04) [2]

Можно и с углами и совсем, только определитесь с проекцией.


 
Yar-Com   (2004-04-28 10:10) [10]

=)
Вот простенький примерчик.

unit Unit1;
interface
uses Windows, Forms;
type  TVertex = record x,y,z : Single;end;  // координаты вершины
     TFace = array [0..3] of Integer;
     TForm1 = class(TForm)
       procedure OnFormPaint(Sender: TObject);
     public
       // функция поворачивает куб на нужный угол затем проецирует.
       procedure RotateAndProject(XAngle, YAngle, ZAngle : Single);
     end;
var  Form1: TForm1;
implementation {$R *.dfm}
Const Scale : Single = 50; // размер куба
   CubeVertices : array [0..7] of TVertex = ((x:-1; y:-1; z:-1),
                                             (x: 1; y:-1; z:-1),
                                             (x: 1; y: 1; z:-1),
                                             (x:-1; y: 1; z:-1),
                                             (x:-1; y:-1; z: 1),
                                             (x: 1; y:-1; z: 1),
                                             (x: 1; y: 1; z: 1),
                                             (x:-1; y: 1; z: 1));
   CubeFaces : array [0..5] of TFace = ((0,1,2,3),
                                        (4,5,6,7),
                                        (0,4,7,3),
                                        (1,5,6,2),
                                        (3,7,6,2),
                                        (0,4,5,1));
   CubeFacesNormals : array [0..5] of TVertex = ((x: 0; y: 0; z: 1),
                                                 (x: 0; y: 0; z:-1),
                                                 (x: 1; y: 0; z: 0),
                                                 (x:-1; y: 0; z: 0),
                                                 (x: 0; y:-1; z: 0),
                                                 (x: 0; y: 1; z: 0));
Var ProjectedVertices : array [0..7] of TPoint;
procedure TForm1.RotateAndProject(XAngle, YAngle, ZAngle : Single);
Var i : Integer; tmp : Single;
begin
   XAngle := XAngle * PI / 180;  YAngle := YAngle * PI / 180; ZAngle := ZAngle * PI / 180;
   for i := 0 to 7 do
    with CubeVertices[i] do
       begin
           // поворачиваем
           tmp := x;
           x := x * cos(XAngle) - y * sin(XAngle);
           y := tmp * sin(XAngle) + y * cos(XAngle);
           tmp := y;
           y := y * cos(YAngle) - z * sin(YAngle);
           z := tmp * sin(YAngle) + z * cos(YAngle);
           tmp := z;
           z := z * cos(ZAngle) - x * sin(ZAngle);
           x := tmp * sin(ZAngle) + x * cos(ZAngle);
           // проецируем
           tmp := ClientWidth / (ClientWidth + z * Scale);
           ProjectedVertices[i].X := Round((ClientWidth / 2) + x * tmp * Scale);
           ProjectedVertices[i].Y := Round((ClientHeight / 2) + y * tmp * Scale);
       end;
   for i := 0 to 5 do
    with CubeFacesNormals[i] do
       begin
           tmp := x;
           x := x * cos(XAngle) - y * sin(XAngle);
           y := tmp * sin(XAngle) + y * cos(XAngle);
           tmp := y;
           y := y * cos(YAngle) - z * sin(YAngle);
           z := tmp * sin(YAngle) + z * cos(YAngle);
           tmp := z;
           z := z * cos(ZAngle) - x * sin(ZAngle);
           x := tmp * sin(ZAngle) + x * cos(ZAngle);
       end;
end;
procedure TForm1.OnFormPaint(Sender: TObject);
Var i, j : Integer; Poly : array [0..3] of TPoint;
begin
   RotateAndProject(90, 10, 30);
   for i := 0 to 5 do if CubeFacesNormals[i].z > 0 then
       begin
           for j := 0 to 3 do Poly[j] := ProjectedVertices[CubeFaces[i][j]];
           Canvas.Polygon(Poly);
       end;
end;
end.


 
X-Disa ©   (2004-05-08 08:08) [11]

Спасибо!


 
X-Disa ©   (2004-05-08 08:54) [12]

Я глянул процедурку, но есть один вопрос. Рисование на канве я вынес в отдельную процедуру, и размер куба сделал переменной:


procedure DrawToCanvas(Bitmap:TBitmap;CubeSize,XAngle,YAngle,ZAngle:integer);
Var i, j : Integer; Poly : array [0..3] of TPoint;
begin
Scale:=CubeSize;
  RotateAndProject(Bitmap,XAngle,YAngle,ZAngle);
  for i := 0 to 5 do if CubeFacesNormals[i].z > 0 then
      begin
          for j := 0 to 3 do Poly[j] := ProjectedVertices[CubeFaces[i][j]];
          Bitmap.Canvas.Polygon(Poly);
      end;
end;


Вопрос такой: Если два раза вызвать эту процедуру с одними и теми же углами, то рисуется разная картинка :(. Что делать?


 
X-Disa ©   (2004-05-08 09:12) [13]

А, нет, все с процедурой нормально. Я ее просто криво вызывал.


 
Mentat   (2004-05-08 11:09) [14]

Гиперкуб круче


 
Franzy ©   (2004-05-08 11:35) [15]

У меня есть решение поуниверсальней. Когда-то давно, еще курсе на третьем, я вывел формулы для проецирования трехмерного пространства на плоскость. Иными словами, эти формулы позволяют рисовать на канвасе трехмерные объекты :)
Вот эти ДВЕ формулы:

pp.x:= CenterX + round( FZoom * ( (x-FRC.x)*cos(ha)+(y-FRC.y)*sin(ha) ));
  pp.y:= CenterY + round( FZoom * (((y-FRC.y)*cos(ha)-(x-FRC.x)*sin(ha))*sin(va)-cos(va)*(z-FRC.z)));

где:
pp : TPoint; - координаты пикселя на канвасе
CenterX, CenterY - координаты фокуса камеры на канвасе (см. ниже)
FRC : трехмерные координаты фокуса камеры, т.е. точки, куда направлен взгляд камеры. (Сама камера располагается на удалении от рисуемого объекта). Вокруг этого фокуса и происходит вращение камеры.
x,y,z - координаты рисуемой точки
FZoom - "увеличение". Нужно воспринимать как масштаб изображения. при FZoom=1 1 ед. измерения в трехмерных координатах будет соответствовать 1 пикселю. При FZoom=100 соответственно, 100 пикселям.
ha и va -horisontal and vertical angles - углы поворота и подъема камеры (в радианах, разумеется). Так, для ортогональной проекции (или оксонметрии??? как она там называется? не помню, блин, давно инженерка была :)) эти углы равны pi/4.

Для вашего случая: положим, есть битмап 200х200, вы хотите в центре нарисовать куб с ребром 100. Тогда CenterX=CenterY=100, а FRC.x=FRC.Y=FRC.z=50, FZoom=1.

Привет от Баумана!


 
X-Disa ©   (2004-05-09 11:53) [16]

Спасибо. Вот у меня еще один вопрос возник, в том примере, как рисовать с невидимыми линиями тоже?


 
X-Disa ©   (2004-05-13 14:46) [17]

А все-таки, как включить невидимые линии?


 
Pa5ha   (2004-05-16 00:41) [18]

Franzy - рулит.
X-Disa - используй ZBUFFER. Другого решения пооригинальнее нету. Можно рисовать только выпуклые многогранники без него.
Yar-Com поподробнее пожалуйста про текстурирование. Можно ветку новую сделать даже ради такого дела. Или мыло свое дай. PLZ!!!



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.031 c
1-1089797537
Anisa
2004-07-14 13:32
2004.08.01
программная сортирвка файлов каталога


4-1087382966
Leon
2004-06-16 14:49
2004.08.01
Можно ли послать сообщение WM_CLOSE и не ждать


14-1089533826
_none_
2004-07-11 12:17
2004.08.01
баг в XP


1-1090288396
НовиЧок
2004-07-20 05:53
2004.08.01
Манифест XP


6-1085766580
Senti
2004-05-28 21:49
2004.08.01
Вопрос по потокам с использование функции GetHostByAddr





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский