Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1

Соединить точки 3D Куба в BuilderC++

15.12.2014, 01:31. Показов 4688. Ответов 29

Студворк — интернет-сервис помощи студентам
Собственно такое задание: Создать 3D куб или любую другую фигуру без использование OpenGl + поворот фигуры за счет нажатия и удержание ЛКМ.

Задание выполнено , но вот отображаются только точки 3D Куба

Помогите сделать отрисовку линий от точек таким образом чтоб был полноценный Куб

Я пытался сделать что то но не получалось , рисовалось от всех точек к 1 координате

вот код
C++
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
    void TForm1::draw()
 
{
     float w= Image1->Width;
     float h = Image1->Height;
     float s;
     if(w<h) s=w/2;
     else s=h/2;
     s = s / 2;
     Image1->Canvas->Brush->Color = RGB(255, 255, 255);
     Image1->Canvas->FillRect(Rect(0, 0, w, h));
     Image1->Canvas->Brush->Color = RGB(0, 127, 255);
     float m1[9];
     float m2[9];
     rotate_x(m1, ay);
     rotate_y(m2, ax);
     float m[9], a,b, v[3];
     multiply(m, m1, m2);
     for(int j=0;j<8;j++)
     {
     for (int i=0; i<8; i++)
     {
 
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
      
        a = w/2 + r[0] * s;
        b = h/2 - r[1]* s;
        Image1->Canvas->Ellipse(a - 5, b - 5, a + 5, b + 5);
        //Image1->Canvas->MoveTo(a,b);        // Пытался реализовать отисовку, но ничего не выходит 
        //Image1->Canvas->LineTo(px[i],py[i]);  // Пытался реализовать отисовку, но ничего не выходит 
     }
 
     }
 
 
 
    }
Исходный текст программы

C++
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//---------------------------------------------------------------------------
#include <math.h>
#include <vcl.h>
#pragma hdrstop
 
#include "ghj.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
        if(lock == true)
        {
       ax = ax + (float) (X - mouse_x);
       Caption = ax;
 
 
 
       ay = ay + (float) (Y - mouse_y);
       Caption = AnsiString (ax) + " " + AnsiString(ay)  ;
          draw();
        }
        mouse_x = X;
        mouse_y =  Y;
 
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::ImageMoseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
        lock=true;        
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ImageMoseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
        lock=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 /*
for (int i = 0; i < 100; i++)
{
        px[i] = ((float) rand() / (float) RAND_MAX) * 2.0 - 1.0;
        py[i] = ((float) rand() / (float) RAND_MAX) * 2.0 - 1.0;
        pz[i] = ((float) rand() / (float) RAND_MAX) * 2.0 - 1.0;
}
*/
 
 
        px[0] = -1; py[0] = 1 ; pz[0] = 1;
        px[1] = 1;  py[1] = 1;  pz[1] = 1 ;
        px[2] = -1;py[2] = -1; pz[2] = 1;
        px[3] = 1 ; py[3] = -1 ;pz[3] =1 ;
        px[4] = -1; py[4] =1 ;  pz[4] =-1;
        px[5] = 1;  py[5] = 1;   pz[5] =  -1;
        px[6] = -1; py[6] = -1; pz[6] = -1;
        px[7] = 1;  py[7] = -1 ; pz[7] = -1;
 
 
}
//---------------------------------------------------------------------------
    void TForm1::draw()
 
{
     float w= Image1->Width;
     float h = Image1->Height;
     float s;
     if(w<h) s=w/2;
     else s=h/2;
     s = s / 2;
     Image1->Canvas->Brush->Color = RGB(255, 255, 255);
     Image1->Canvas->FillRect(Rect(0, 0, w, h));
     Image1->Canvas->Brush->Color = RGB(0, 127, 255);
     float m1[9];
     float m2[9];
     rotate_x(m1, ay);
     rotate_y(m2, ax);
     float m[9], a,b, v[3];
     multiply(m, m1, m2);
     for(int j=0;j<8;j++)
     {
     for (int i=0; i<8; i++)
     {
 
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
      
        a = w/2 + r[0] * s;
        b = h/2 - r[1]* s;
        Image1->Canvas->Ellipse(a - 5, b - 5, a + 5, b + 5);
        //Image1->Canvas->MoveTo(a,b);        // ÏÛÒÀËÑß ÑÎÅÄÅÍÈÒÜ ÍÎ ÍÈ×ÃÅÎ ÍÅ ÂÛØËÎ ):
        //Image1->Canvas->LineTo(px[i],py[i]);  // ÏÛÒÀËÑß ÑÎÅÄÅÍÈÒÜ ÍÎ ÍÈ×ÃÅÎ ÍÅ ÂÛØËÎ ):
     }
 
     }
 
 
 
    }
 
//---------------------------------------------------------------------------
  inline void TForm1::rotate_x(float m1[9], float ay)
  {
  const float r = ay*M_PI / 180.0f;
  const float ca = cos (r);
  const float sa = sin (r);
  m1[0]=1.0f; m1[1]=0.0f; m1[2]= 0.0f;
  m1[3]=0.0f; m1[4]= ca; m1[5]= -sa;
  m1[6]=0.0f; m1[7]=sa; m1[8]= ca;
    }
//---------------------------------------------------------------------------
  inline void TForm1::rotate_y(float m2[9], float ax)
  {
  const float r = ax*M_PI / 180.0f;
  const float ca = cos (r);
  const float sa = sin (r);
  m2[0]=ca; m2[1]=0.0f; m2[2]= sa;
  m2[3]=0.0f; m2[4]= 1.0f; m2[5]= 0.0f;
  m2[6]=-sa; m2[7]=0.0f; m2[8]= ca;
  }
 
 
//---------------------------------------------------------------------------
  inline void TForm1::multiply(float m[9], const float a[9], const float b[9])
 {
        m[0] = a[0] * b [0] + a[1] * b[3] + a[2] * b[6];
        m[1] = a[0] * b [1] + a[1] * b[4] + a[2] * b[7];
        m[2] = a[0] * b [2] + a[1] * b[5] + a[2] * b[8];
        m[3] = a[3] * b [0] + a[4] * b[3] + a[5] * b[6];
        m[4] = a[3] * b [1] + a[4] * b[4] + a[5] * b[7];
        m[5] = a[3] * b [2] + a[4] * b[5] + a[5] * b[8];
        m[6] = a[6] * b [0] + a[7] * b[3] + a[8] * b[6];
        m[7] = a[6] * b [1] + a[7] * b[4] + a[8] * b[7];
        m[8] = a[6] * b [2] + a[7] * b[5] + a[8] * b[8];
 
 
 }
 //---------------------------------------------------------------------------
  inline void  TForm1::transform ( float r[3], float v[3],float m[9])
  {
        r[0] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2];
        r[1] = m[3] * v[0] + m[4] * v[1] + m[5] * v[2];
        r[2] = m[6] * v[0] + m[7] * v[1] + m[8] * v[2];
  }
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.12.2014, 01:31
Ответы с готовыми решениями:

Определить взаимное расположение точки и куба
Формат входного файла В первой строке три числа – координаты точки. В следующих четырех строках по три числа – координаты вершин...

соединить 2 точки
Всем привет :) Как можно соединить 2 точки (линией с поворотом на 90градусов(не просто по диагонали) ), Используя координаты и...

Нужно соединить точки
Сделал граффик по уравнению, но как теперь соединить точки? package rafik; import java.applet.Applet; import java.awt.Color; import...

29
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
15.12.2014, 03:21
А где ghj.h (может там описываются все непонятные переменные)?
И учти, что вряд ли достаточно будет просто нарисовать линии. Наверняка придется их преобразованием заниматься. Или я ошибаюсь?
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
15.12.2014, 10:08
Значит делаешь примерно так : заводишть массив int Lines[12][2] в него пишешь номера точек линий.
точки при трансформации тоже в отдельный массив пихаешь, к примеру ТPoint Transformed[8];
Ну а при отрисовке
C++
1
2
3
4
for(int i=0;i<12;i++){ 
     Image1->Canvas->MoveTo(Transformed[Lines[i][0]].x,Transformed[Lines[i][0]].y);
     Image1->Canvas->LineTo(Transformed[Lines[i][1]].x,Transformed[Lines[i][1]].y);
}
Добавлено через 17 минут
Вот кстати для примера отрисовка куба, только куб закрашенный и без задних стенок.
C++
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
struct TCellFaces{
       TPoint Top[4];
       TPoint Bottom[4];
       TPoint Left[4];
       TPoint Right[4];
};
void __fastcall TMapRender::DrawSelectedRegion(Graphics::TBitmap *Bitmap,T3DRegion Region){
                TCellFaces DrawFaces;
                DrawFaces.Top[0]=Project(T3DPoint(Region.Start.x,Region.Start.y,Region.End.z+1));
                DrawFaces.Top[1]=Project(T3DPoint(Region.End.x+1,Region.Start.y,Region.End.z+1));
                DrawFaces.Top[2]=Project(T3DPoint(Region.End.x+1,Region.End.y+1,Region.End.z+1));
                DrawFaces.Top[3]=Project(T3DPoint(Region.Start.x,Region.End.y+1,Region.End.z+1));
                TPoint Dz=Steps(T3DPoint(0,0,-Region.Dimensions.z));
                for (int i = 0; i < 4; i++)DrawFaces.Bottom[i]=DrawFaces.Top[i]+Dz;
                DrawFaces.Left[0]=DrawFaces.Bottom[2];
                DrawFaces.Left[1]=DrawFaces.Bottom[3];
                DrawFaces.Left[2]=DrawFaces.Top[3];
                DrawFaces.Left[3]=DrawFaces.Top[2];
                DrawFaces.Right[0]=DrawFaces.Bottom[2];
                DrawFaces.Right[1]=DrawFaces.Top[2];
                DrawFaces.Right[2]=DrawFaces.Top[1];
                DrawFaces.Right[3]=DrawFaces.Bottom[1];
                Bitmap->Canvas->Polygon(DrawFaces.Right,3);
                Bitmap->Canvas->Brush->Color=TColor(0x9F00AF);
                Bitmap->Canvas->Polygon(DrawFaces.Left,3);
                Bitmap->Canvas->Brush->Color=TColor(0xAF00AF);
                Bitmap->Canvas->Polygon(DrawFaces.Top,3);
}
функция Project() аналог
C++
1
2
3
        transform(r, v, m);     
        a = w/2 + r[0] * s;
        b = h/2 - r[1]* s;
0
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1
15.12.2014, 19:48  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Значит делаешь примерно так : заводишть массив int Lines[12][2] в него пишешь номера точек линий.
точки при трансформации тоже в отдельный массив пихаешь, к примеру ТPoint Transformed[8];
Ну а при отрисовке

C++
1
2
3
4
for(int i=0;i<12;i++){ 
       Image1->Canvas->MoveTo(Transformed[Lines[i][0]].x,Transformed[Lines[i][0]].y);
       Image1->Canvas->LineTo(Transformed[Lines[i][1]].x,Transformed[Lines[i][1]].y);
}
не могли бы вы помочь с этим? куда и как а то я пока в полумраке сижу и не понимаю куда втыкать это все.. Если не сложно =\

файлы программы прикрепил к сообщению
Вложения
Тип файла: rar 3дкуб.rar (370.3 Кб, 64 просмотров)
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
15.12.2014, 20:59
Значится там где задаешь координаты вершин куба добавляешь:
C++
1
2
3
4
Lines[0][0]=0; Lines[0][1]=1;
Lines[1][0]=1; Lines[0][1]=2;
Lines[2][0]=2; Lines[0][1]=3;
Lines[3][0]=3; Lines[0][1]=0;
и т д - это я написал для верхней грани так же делаешь для нижней а потом для линий которые остались
там где у тебя отрисовываются точки делаешь так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TPoint Transformed[8];
for (int i=0; i<8; i++)
     {
 
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
      
        TPoint[i].x = w/2 + r[0] * s+0.5;
        TPoint[i].y = h/2 - r[1]* s+0.5;
        Image1->Canvas->Ellipse(TPoint[i].x-5, TPoint[i].y-5 ,TPoint[i].x + 5, TPoint[i].y + 5);
     } 
     for(int i=0;i<12;i++){ 
          Image1->Canvas->MoveTo(Transformed[Lines[i][0]].x,Transformed[Lines[i][0]].y);
          Image1->Canvas->LineTo(Transformed[Lines[i][1]].x,Transformed[Lines[i][1]].y);
     }
в хидре в секции private:
добавь int Lines[12][2];
0
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1
15.12.2014, 21:46  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Значится там где задаешь координаты вершин куба добавляешь:
Так я , сделал как написали, выдает ошибку =\

[C++ Error] ghj.cpp(112): E2108 Improper use of typedef 'TPoint'

C++
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
    void TForm1::draw()
{
     float w= Image1->Width;
     float h = Image1->Height;
     float s;
     if(w<h) s=w/2;
     else s=h/2;
     s = s / 2;
     Image1->Canvas->Brush->Color = RGB(255, 255, 255);
     Image1->Canvas->FillRect(Rect(0, 0, w, h));
     Image1->Canvas->Brush->Color = RGB(0, 127, 255);
     float m1[9];
     float m2[9];
     rotate_x(m1, ay);
     rotate_y(m2, ax);
     float m[9], a,b, v[3];
     multiply(m, m1, m2);
     for(int j=0;j<8;j++)
     {
     TPoint Transformed[8];
     for (int i=0; i<8; i++)
     {
 
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
 
        TPoint[i].x = w/2 + r[0] * s+0.5; // ОШИБКА ( TPoint[i].x=.... )
        TPoint[i].y = h/2 - r[1]* s+0.5;
        Image1->Canvas->Ellipse(TPoint[i].x-5, TPoint[i].y-5 ,TPoint[i].x + 5, TPoint[i].y + 5);
     }
     for(int i=0;i<12;i++){
          Image1->Canvas->MoveTo(Transformed[Lines[i][0]].x,Transformed[Lines[i][0]].y);
          Image1->Canvas->LineTo(Transformed[Lines[i][1]].x,Transformed[Lines[i][1]].y);
     }
 
     }
 
 
 
 
    }
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
16.12.2014, 00:06
Цитата Сообщение от Nyiann Посмотреть сообщение
Так я , сделал как написали, выдает ошибку =\
[C++ Error] ghj.cpp(112): E2108 Improper use of typedef 'TPoint'
Соории, совсем мне в другой теме голову задурили
C++
1
2
3
 TPoint[i].x = w/2 + r[0] * s+0.5; // ОШИБКА ( TPoint[i].x=.... )
        TPoint[i].y = h/2 - r[1]* s+0.5;
        Image1->Canvas->Ellipse(TPoint[i].x-5, TPoint[i].y-5 ,TPoint[i].x + 5, TPoint[i].y + 5);
В этих строчках TPoint замени на Transformed
0
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1
16.12.2014, 00:38  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Соории, совсем мне в другой теме голову задурили
C++
1
2
3
TPoint[i].x = w/2 + r[0] * s+0.5; // ОШИБКА ( TPoint[i].x=.... )
           TPoint[i].y = h/2 - r[1]* s+0.5;
           Image1->Canvas->Ellipse(TPoint[i].x-5, TPoint[i].y-5 ,TPoint[i].x + 5, TPoint[i].y + 5);
В этих строчках TPoint замени на Transformed
Помогло , заменил все работает (:

как я понял , то Lines[12][2] - это массив линий, но вот как заполнить для другой стороны?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        px[0] = -1; py[0] = 1 ; pz[0] = 1; 
        px[1] = 1;  py[1] = 1;  pz[1] = 1 ;
        px[2] = -1;py[2] = -1; pz[2] = 1;
        px[3] = 1 ; py[3] = -1 ;pz[3] =1 ;
        px[4] = -1; py[4] =1 ;  pz[4] =-1;
        px[5] = 1;  py[5] = 1;   pz[5] =  -1;
        px[6] = -1; py[6] = -1; pz[6] = -1;
        px[7] = 1;  py[7] = -1 ; pz[7] = -1;
 
        Lines[0][0]=0; Lines[0][1]=1;//Работает
        Lines[1][0]=1; Lines[0][1]=2;//Работает
        Lines[2][0]=2; Lines[0][1]=3;//Работает
        Lines[3][0]=3; Lines[0][1]=0;//Работает
 
        Lines[0][0]=0; Lines[0][2]=1;//Как 2ую и тд сторону заполнить?
        Lines[1][0]=1; Lines[0][2]=2;//Как 2ую и тд сторону заполнить?
        Lines[2][0]=2; Lines[0][2]=3;//Как 2ую и тд сторону заполнить?
        Lines[3][0]=3; Lines[0][2]=0;//Как 2ую и тд сторону заполнить?
Мне завтра сдать надо просто это все а я вот на ночь отложил зачем то =\
что-то не соображаю, я принцип понял как (: но вот никак не додуматься ( даже если вы все расписали) как всеж сделать для другой стороны =\
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
16.12.2014, 01:30
Лучший ответ Сообщение было отмечено Nyiann как решение

Решение

Можно рисовать линии сразу в твоей функции draw().
Дополнительных преобразований не требуется.
При желании рисуй "шарики в углах" после линий, чтобы линии поверх "шариков" не отображались (т.е. убираешь строку 30 и вставляешь ее после всех MoveTo и LineTo, не забывая про цикл от 0 до 7 включительно, заменив a и b на x[i] и y[i] соответственно).
C++
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
void TForm1::draw()
{
     float w= Image1->Width;
     float h = Image1->Height;
     float s;
     if(w<h) s=w/2;
     else s=h/2;
     s = s / 2;
     Image1->Canvas->Brush->Color = RGB(255, 255, 255);
     Image1->Canvas->FillRect(Rect(0, 0, w, h));
     Image1->Canvas->Brush->Color = RGB(0, 127, 255);
     float m1[9];
     float m2[9];
     rotate_x(m1, ay);
     rotate_y(m2, ax);
     float m[9], a,b, v[3], x[8], y[8];
     multiply(m, m1, m2);
     for (int i=0; i<8; i++)
     {
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
 
        a = w/2 + r[0] * s;
        b = h/2 - r[1]* s;
        x[i] = a;
        y[i] = b;
        Image1->Canvas->Ellipse(a - 5, b - 5, a + 5, b + 5);
     }
     Image1->Canvas->MoveTo(x[5], y[5]);
     Image1->Canvas->LineTo(x[1], y[1]);
     Image1->Canvas->LineTo(x[0], y[0]);
     Image1->Canvas->LineTo(x[4], y[4]);
     Image1->Canvas->LineTo(x[5], y[5]);
 
     Image1->Canvas->LineTo(x[7], y[7]);
     Image1->Canvas->LineTo(x[6], y[6]);
     Image1->Canvas->LineTo(x[4], y[4]);
 
     Image1->Canvas->MoveTo(x[7], y[7]);
     Image1->Canvas->LineTo(x[3], y[3]);
     Image1->Canvas->LineTo(x[2], y[2]);
     Image1->Canvas->LineTo(x[6], y[6]);
 
     Image1->Canvas->LineTo(x[2], y[2]);
     Image1->Canvas->LineTo(x[0], y[0]);
 
     Image1->Canvas->MoveTo(x[1], y[1]);
     Image1->Canvas->LineTo(x[3], y[3]);
}
Миниатюры
Соединить точки 3D Куба в BuilderC++  
1
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1
16.12.2014, 01:41  [ТС]
Цитата Сообщение от gunslinger Посмотреть сообщение
Можно рисовать линии сразу в твоей функции draw().
Дополнительных преобразований не требуется.
При желании рисуй "шарики в углах" после линий, чтобы линии поверх "шариков" не отображались (т.е. убираешь строку 30 и вставляешь ее после всех MoveTo и LineTo, не забывая про цикл от 0 до 7 включительно, заменив a и b на x[i] и y[i] соответственно).
Спасибо большое (:
Я так пытался делать, но в цикл все впихивал ):

Все Тема закрыта получается (:
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
16.12.2014, 02:40
Цитата Сообщение от gunslinger Посмотреть сообщение
Можно рисовать линии сразу в твоей функции draw().
Дополнительных преобразований не требуется.
Ну зачем ты человека говнокод писать учишь? Ну это у него первая лаба по ВГ, потом буде покруче, пока не дойдет практически до полноценного графического конвейера. А как он в абстрактной фигуре (неизвестной на момент компиляции программы топологии) так будет каждое ребро прорисовывать?
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
16.12.2014, 03:34
Какое задание (программа) - такой ответ.
К тому же Lines твои он пока не понимает.
Я не претендую, чтобы мой код повесили в рамочку и молились на него перед сном.
Человек получает то, что желает.
Вариант решения лучше придумать не смог.
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
16.12.2014, 16:27
Улучшил код отрисовки линий.
C++
1
2
3
4
5
6
7
8
9
10
     int lines[4][4] = {0, 1, 2, 4,
                        5, 1, 4, 7,
                        3, 1, 2, 7,
                        6, 2, 4, 7};
     for (int i = 0; i < 4; i++)
       for (int j = 1; j < 4; j++)
       {
         Image1->Canvas->MoveTo(x[lines[i][0]], y[lines[i][0]]);
         Image1->Canvas->LineTo(x[lines[i][j]], y[lines[i][j]]);
       }
Итого
C++
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
void TForm1::draw()
{
     float w= Image1->Width;
     float h = Image1->Height;
     float s;
     if(w<h) s=w/2;
     else s=h/2;
     s = s / 2;
     Image1->Canvas->Brush->Color = RGB(255, 255, 255);
     Image1->Canvas->FillRect(Rect(0, 0, w, h));
     Image1->Canvas->Brush->Color = RGB(0, 127, 255);
     float m1[9];
     float m2[9];
     rotate_x(m1, ay);
     rotate_y(m2, ax);
     float m[9], a,b, v[3], x[8], y[8];
     multiply(m, m1, m2);
     for (int i=0; i<8; i++)
     {
        v[0] = px[i];
        v[1] = py[i];
        v[2] = pz[i];
        float r[3];
        transform(r, v, m);
 
        a = w/2 + r[0] * s;
        b = h/2 - r[1]* s;
        x[i] = a;
        y[i] = b;
     }
 
     int lines[4][4] = {0, 1, 2, 4,
                        5, 1, 4, 7,
                        3, 1, 2, 7,
                        6, 2, 4, 7};
     for (int i = 0; i < 4; i++)
       for (int j = 1; j < 4; j++)
       {
         Image1->Canvas->MoveTo(x[lines[i][0]], y[lines[i][0]]);
         Image1->Canvas->LineTo(x[lines[i][j]], y[lines[i][j]]);
       }
 
     for (int i=0; i<8; i++)
     {
       Image1->Canvas->Ellipse(x[i] - 5, y[i] - 5, x[i] + 5, y[i] + 5);
//       Image1->Canvas->TextOutA(x[i]+10, y[i]-5, i);
     }
}
Миниатюры
Соединить точки 3D Куба в BuilderC++  
0
16.12.2014, 16:39

Не по теме:

gunslinger, тут прям напрашивается теперь задействовать MouseDown. Один шаг до три де редактора.

0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
16.12.2014, 17:24
тогда уже вот так:
C++
1
2
x[i] = w/2 + s*r[0]/(r[2]+2)) ;
y[i] = h/2 -  s*r[1]/(r[2]+2));
И опять поменять отрисовку на непривязанную к топологии
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
16.12.2014, 22:14
Fulcrum_013, ты бы уже как-нибудь обозначил принцип отвязки от топологии, а-то страшно уже всем от обилия заумных слов.
Прослойка из множества связей пар точек между расчетной и выводящей частями алгоритма? Или, может, есть что-то поинтересней на уме?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
17.12.2014, 01:38
Цитата Сообщение от BRcr Посмотреть сообщение
Прослойка из множества связей пар точек между расчетной и выводящей частями алгоритма?
Да действительно, в вашем варианте индекс-буффера просто TriangleFan не сразу просматривается.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
17.12.2014, 19:38
В моем варианте веер треугольников не подразумевается изначально и просматриваться не должен в принципе. Множество треугольников, разделяющих вершину - это уже спецификация формы, которую надо знать на этапе отображения. Множество пар точек как раз не ограничивает нас никакой конкретной формой и может задавать любой произвольный объект.

Я это все просто к тому, что критиковать надо так, чтобы тебя понимали. А-то говнокодом ругнулся и зашифровался за топологией. Нехорошо.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
18.12.2014, 08:58
Цитата Сообщение от BRcr Посмотреть сообщение
В моем варианте веер треугольников не подразумевается изначально и просматриваться не должен в принципе
Но он там есть. если сделать вот так
C++
1
2
3
4
5
6
7
8
9
 for (int i = 0; i < 4; i++)
       for (int j = 1; j < 4; j++)
       {
         Image1->Canvas->MoveTo(x[lines[i][0]], y[lines[i][0]]);
         Image1->Canvas->LineTo(x[lines[i][j]], y[lines[i][j]]);
         if(j<3)Image1->Canvas->LineTo(x[lines[i][j+1]], y[lines[i][j+1]]);
       }
       Image1->Canvas->LineTo(x[lines[i][1]], y[lines[i][1]]);
}
то он даже будет виден визуально.
Цитата Сообщение от BRcr Посмотреть сообщение
Множество пар точек как раз не ограничивает нас никакой конкретной формой и может задавать любой произвольный объект
Да для WireFrame оптимальней именно так. Ваш же вариант индекс-буффера - список граней, который более оптимален для закраски.

Добавлено через 15 минут
Цитата Сообщение от BRcr Посмотреть сообщение
А-то говнокодом ругнулся и зашифровался за топологией
Ну говнокод это по поводу кучи вызовов которые можно заменить массивом примитивов и циклом. А какая бы ни была топология примитива, на массив которых разбивается отображаемая модель, при такой замене от топологии модели(в данном случае куба) функция отрисовки отвязывается.
1
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
18.12.2014, 15:43
Изменил программу: при удержании ЛКМ фигура вращается (раньше при клике любой кнопкой мыши), по колесику мыши изменяется масштаб (вверх - больше, вниз - меньше), по ПКМ двигаются "угловые точки" (нужно кликнуть по точке и двигать мышь), пока правая кнопка мыши зажата.
Есть лишь одна проблема - "сдвинутые углы" при вращении отображаются (координаты пересчитываются) неверно.
См. строки 32-36 в cpp.

cpp:
C++
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//---------------------------------------------------------------------------
#include <math.h>
#include <vcl.h>
#pragma hdrstop
 
#include "ghj.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
  if (lock == 1)
  {
    ax += (float) (X - mouse_x);
    ay += (float) (Y - mouse_y);
    Caption = String((int)ax) + " " + String((int)ay);
    draw();
  }
  if (move == 1)
  {
    x[ball] = X;
    y[ball] = Y;
 
    // хз как пересчитывать положение смещенных точек при вращении
    // можно перенести в Image1MouseUp
    px[ball] = sign(px[ball]) * X / xdif;
    py[ball] = sign(py[ball]) * Y / ydif;
    pz[ball] = sign(pz[ball]) * sqrt(px[ball] * px[ball] + py[ball] * py[ball]);
 
    draw();
  }
  mouse_x = X;
  mouse_y = Y;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
  if (Button == mbLeft)
    lock = 1;
  if (Button == mbRight)
    for (int i=0; i<8; i++)
      if (X >= x[i]-5 && X <= x[i]+5 && Y >= y[i]-5 && Y <= y[i]+5)
      {
        xdif = X;
        ydif = Y;
        move = 1;
        ball = i;
        break;
      }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
  lock = 0;
  move = 0;
  ball = 8;  // если убрать эту строку, то при вращении "смещенная" точка
  // будет оставаться на месте
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  w = Image1->Width;
  h = Image1->Height;
  s = w < h ? w/4 : h/4;
 
  px[0] = -1; py[0] = 1;  pz[0] = 1;
  px[1] = 1;  py[1] = 1;  pz[1] = 1 ;
  px[2] = -1; py[2] = -1; pz[2] = 1;
  px[3] = 1 ; py[3] = -1; pz[3] =1 ;
  px[4] = -1; py[4] = 1;  pz[4] = -1;
  px[5] = 1;  py[5] = 1;  pz[5] = -1;
  px[6] = -1; py[6] = -1; pz[6] = -1;
  px[7] = 1;  py[7] = -1; pz[7] = -1;
  ball = 8;
  rdif = 1;
}
//---------------------------------------------------------------------------
void TForm1::draw()
{
  Image1->Canvas->Brush->Color = RGB(255, 255, 255);
  Image1->Canvas->FillRect(Rect(0, 0, w, h));
  Image1->Canvas->Brush->Color = RGB(0, 127, 255);
  float m1[9], m2[9];
 
  for (int i=0; i<8; i++)
  if (i != ball)
  {
    rotate_x(m1, ay);
    rotate_y(m2, ax);
 
    float m[9], a, b, v[3];
    multiply(m, m1, m2);
 
    v[0] = px[i];
    v[1] = py[i];
    v[2] = pz[i];
    float r[3];
    transform(r, v, m);
 
    a = w/2 + r[0] * s;
    b = h/2 - r[1] * s;
    x[i] = a;
    y[i] = b;
  }
 
  int lines[4][4] = {0, 1, 2, 4,
                     5, 1, 4, 7,
                     3, 1, 2, 7,
                     6, 2, 4, 7};
  for (int i = 0; i < 4; i++)
    for (int j = 1; j < 4; j++)
    {
      Image1->Canvas->MoveTo(x[lines[i][0]], y[lines[i][0]]);
      Image1->Canvas->LineTo(x[lines[i][j]], y[lines[i][j]]);
    }
 
  for (int i=0; i<8; i++)
  {
    Image1->Canvas->Ellipse(x[i] - 5, y[i] - 5, x[i] + 5, y[i] + 5);
//    Image1->Canvas->TextOutA(x[i]+10, y[i]-5, i);
  }
}
//---------------------------------------------------------------------------
inline void TForm1::rotate_x(float m1[9], float ay)
{
  const float r = ay*M_PI / 180.0f;
  const float ca = cos(r);
  const float sa = sin(r);
  m1[0]=1.0f; m1[1]=0.0f; m1[2]=0.0f;
  m1[3]=0.0f; m1[4]=ca;   m1[5]=-sa;
  m1[6]=0.0f; m1[7]=sa;   m1[8]=ca;
}
//---------------------------------------------------------------------------
inline void TForm1::rotate_y(float m2[9], float ax)
{
  const float r = ax*M_PI / 180.0f;
  const float ca = cos(r);
  const float sa = sin(r);
  m2[0]=ca;   m2[1]=0.0f; m2[2]=sa;
  m2[3]=0.0f; m2[4]=1.0f; m2[5]=0.0f;
  m2[6]=-sa;  m2[7]=0.0f; m2[8]=ca;
}
//---------------------------------------------------------------------------
inline void TForm1::multiply(float m[9], const float a[9], const float b[9])
{
  m[0] = a[0] * b [0] + a[1] * b[3] + a[2] * b[6];
  m[1] = a[0] * b [1] + a[1] * b[4] + a[2] * b[7];
  m[2] = a[0] * b [2] + a[1] * b[5] + a[2] * b[8];
  m[3] = a[3] * b [0] + a[4] * b[3] + a[5] * b[6];
  m[4] = a[3] * b [1] + a[4] * b[4] + a[5] * b[7];
  m[5] = a[3] * b [2] + a[4] * b[5] + a[5] * b[8];
  m[6] = a[6] * b [0] + a[7] * b[3] + a[8] * b[6];
  m[7] = a[6] * b [1] + a[7] * b[4] + a[8] * b[7];
  m[8] = a[6] * b [2] + a[7] * b[5] + a[8] * b[8];
}
//---------------------------------------------------------------------------
inline void  TForm1::transform ( float r[3], float v[3],float m[9])
{
  if (rdif <= 0.5)  // наименьший масштаб
    rdif = 0.5;
  if (rdif >= 5)  // наибольший масшатаб
    rdif = 5;
  r[0] = (m[0] * v[0] + m[1] * v[1] + m[2] * v[2]) / rdif;
  r[1] = (m[3] * v[0] + m[4] * v[1] + m[5] * v[2]) / rdif;
  r[2] = (m[6] * v[0] + m[7] * v[1] + m[8] * v[2]) / rdif;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheelUp(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled)
{
  rdif += 0.01;
  draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheelDown(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled)
{
  rdif -= 0.01;
  draw();
}
//---------------------------------------------------------------------------
h:
C++
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
//---------------------------------------------------------------------------
 
#ifndef ghjH
#define ghjH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TImage *Image1;
        void __fastcall Image1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y);
        void __fastcall Image1MouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
        void __fastcall Image1MouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormMouseWheelUp(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled);
        void __fastcall FormMouseWheelDown(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled);
 
private:    // User declarations
float w, h, s;
bool lock, move;
int ball, xdif, ydif;
int mouse_x;
float ax;
int mouse_y;
float ay;
float px[8], py[8], pz[8], x[8], y[8], rdif;
void draw();
void rotate_x(float m1[9], float ay);
void rotate_y(float m2[9], float ax);
void multiply(float m[9], const float a[9], const float b[9]);
void transform (float r[3], float v[3], float m[9]);
int sign (float number)
{
  if (number > 0)
    return 1;
  if (number < 0)
    return -1;
  if (number == 0)
    return 0;
};
 
public:     // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Миниатюры
Соединить точки 3D Куба в BuilderC++  
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.12.2014, 15:43
Помогаю со студенческими работами здесь

Соединить точки на canvas
Народ как можно сделать так, что бы несколько точек на canvas последовательно соединились. Если изначально разметка такая. &lt;style...

Как соединить точки линией?
Имеется множество точек на графике. Как их соединить одной кривой?

Соединить точки на плоскости. QPaint
Здравствуйте, Появилась небольшая проблема: есть набор точек с координатами (x,y) хотелось бы в своем виджете нарисовать кривые,...

Соединить точки плавной кривой
Здравствуйте! Вопрос прозвучит странно, но имеется ряд точек, и их нужно соединить кривой и построить такой график? Можно ли это...

Как соединить 2 точки доступа Wi-Fi?
Дело такое, есть 2 здания, расстояние между ними 100 метров или меньше. В здании1 стоит локальная сеть подключенная к интернету, на здании2...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru