### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Handle 3D Coordinates on a canvas  (Read 437 times)

#### Weitentaaal

• Sr. Member
• Posts: 418
• Weitental is a very beautiful garbage depot.
##### Handle 3D Coordinates on a canvas
« on: May 24, 2022, 12:53:51 pm »
Hello,

so I wrote a program that can build some structures with blocks. However, I have certain problems with the return of 3D coordinates when clicking on the canvas. My predecessor who worked on this project had written a function which should calculate this. But the return values are not always correct. Could someone help me here on the hint. In the attachment is a picture. the depth level is steered with the arrows on the right side, whereby on the arrows must be clicked.

So i don't realy know how i get the correct X, Y Values out of the Canvas, because the Cubes are stretched. Also i do have my difficulties to handle resizing of the whole Building Area.

Here my current Code:
Code: Pascal  [Select][+][-]
1.    m3D.X:= -1;
2.    m3D.Y:= -1;
3.    m3D.Z:= -1;
4.    If (MbDownOnDrw) and (Assigned(NewCube) Then Begin
5.       LastX:= MoveHist[NMoves].X;
6.       LastY:= MoveHist[NMoves].Y;
7.       If (LastX = 0) and (LastY = 0) Then
8.          Exit;
9.       // Richtung der Maus bestimmen
10.       If (LastX > 0) And (LastY > 0) Then Begin
11.          // Winkel der letzten Mausbewegung bestimmen
12.          If Abs(ActuX - LastX) = 0 Then begin
13.             Angle:= 90;
14.          end
15.          else begin
16.             Angle:= arctan(Abs(ActuY - LastY) / Abs(ActuX - LastX)) * (180 / 3.141592); //Bogenmaß -> grad
17.          End;
18.
19.          If ActuX - LastX >= 0 Then begin // Bewegung nach rechts
20.             XRicht:= 1;
21.          end
22.          else begin  // Bewegung nach Links
23.             XRicht:= -1;
24.          end;
25.          If ActuY - LastY <= 0 Then Begin // Bewegung nach oben
26.             YRicht:= 1;
27.          end
28.          else begin
29.             YRicht:= -1;
30.          end;
31.
32.          If (XRicht = 1) and (YRicht = 1) Then begin // Winkel in Segment 1 (0h bis 3h)übernehmen
33.             Angle:= Angle;
34.          end
35.          else if (XRicht = -1) and (YRicht = 1) then begin // Winkel in Segment 2 (9h bis 12h)
36.             Angle:= 90 + (90 - Angle);
37.          end
38.          else if (XRicht = -1) and (YRicht = -1) then begin // Winkel in Segment 3 (6h bis 9h)
39.             Angle:= 180 + Angle;
40.          end
41.          else if (XRicht = 1) and (YRicht = -1) then begin
42.             Angle:= 270 + (90 - Angle);
43.          end;
44.          // Bereiche aufteilen in primär zu ändernde Achse
45.          MausRicht:= '';
46.          If ((Angle >= 0) And (Angle < 20)) Or ((Angle >= 340) and (Angle <= 360)) Or ((Angle >=110) and (Angle < 200)) Then begin
47.             MausRicht:= 'X';
48.          end
49.          else if ((Angle >= 20) and (Angle <= 70)) Or ((Angle >= 200) and (Angle < 250)) Then begin
50.             MausRicht:= 'Y';
51.          end
52.          else if ((Angle > 70) and (Angle < 110)) Or ((Angle >= 250) And (Angle < 340)) Then begin
53.             MausRicht:= 'Z';
54.          end;
55.          If Mausricht = '' Then
56.             ShowMessage('Mausrichtungswinkel kontrollieren!');
57.       End;
58.
59.       CDrw:= CoordRef(ActuX, ActuY, False);
60.       cX:= CDrw.X;
61.       cY:= CDrw.Y;
62.       // auf Werkzeugfläche?
63.       If (CDrw.X > ConstArea.X) and not IsMouseOnRubbish Then
64.          Exit;
65.
66.       If LastWkzPos.X = -1 Then begin
67.          // erste Position im Konstruktionsfeld
68.          // X berechnen, wobei Y im ersten Schritt in der Mitte bei -3 liegt
69.          If BahnYFix = -1 Then
70.             AcY:= 2
71.          else
72.             AcY:= BahnYFix - 1;
73.
74.          AcX:= cX + AcY / 2;
75.          AcZ:= cY + AcY / 2;
76.       end
77.       else begin
78.          LastcY:= LastWkzPos.Z - LastWkzPos.Y / 2;
79.          DeltaCy:= cY - LastcY;
80.          Ok3DCoord:= True;
81.
82.          If BahnYFix = -1 Then Begin
83.             repeat
84.                If MausRicht = 'Y' Then begin
85.                   // Änderung zur neuen cY Position primär auf Y anwenden
86.                   If DeltaCy > 0 Then
87.                      AcY:= LastWkzPos.Y - Abs(DeltaCy) * 2
88.                   else
89.                   AcY:= LastWkzPos.Y + Abs(DeltaCy) * 2;
90.
91.                   AcZ:= LastWkzPos.Z;
92.
93.                   If (AcY < 0) or (AcY > ConstArea.Y - CubeSize) Then begin
94.                      MausRicht:= 'Z';
95.                   end;
96.                end;
97.                If MausRicht = 'Z' Then begin
98.                   // Änderung zur neuen cY Position primär auf Z anwenden
99.                   If DeltaCy > 0 Then
100.                      AcZ:= LastWkzPos.Z + Abs(DeltaCy)
101.                   else
102.                      AcZ:= LastWkzPos.Z - Abs(DeltaCy);
103.
104.                   AcY:= LastWkzPos.Y;
105.
106.                   If MausRicht = 'X' Then begin
107.                      // Änderung an neuer cY Position auf Y und Z aufteilen
108.                      If DeltaCy > 0 Then begin
109.                         AcZ:= LastWkzPos.Z + Abs(DeltaCy) / 3;
110.                         AcY:= LastWkzPos.Y - Abs(DeltaCy) / 3 * 2;
111.                      end
112.                      else begin
113.                         AcZ:= LastWkzPos.Z - Abs(DeltaCy) / 3;
114.                         AcY:= LastWkzPos.Y + Abs(DeltaCy) / 3 * 2;
115.                      end;
116.                      Ok3DCoord:= True;
117.                   end;
118.
119.                end;
120.                AcX:= cX + AcY / 2;
121.             until Ok3DCoord;
122.          end
123.          else begin
124.             AcY:= BahnYFix - 1;
125.             AcZ:= cY + AcY / 2;
126.             AcX:= cX + AcY / 2;
127.          end;
128.       End;
129.       LastWkzPos.X:= AcX;
130.       LastWkzPos.Y:= AcY;
131.       LastWkzPos.Z:= AcZ;
132.       // Aus AcX, AcY und AcZ TcX und TcY berechnen
133.       If BahnYFix <> -1 Then begin
134.          TcX:= AcX - AcY / 2;
135.          If TcX <> cX Then
136.             AcX:= cX + AcY / 2;
137.          TcY:= AcZ - AcY / 2;
138.          If Int(TcY * 10000) <> Int(cY * 10000) Then begin
139.             // Y behalten und Z neu ausrechnen
140.             AcZ:= cY + AcY / 2;
141.          end;
142.       End;
143.       // Aktuelle 3D Position des Würfels merken
144.       m3D.X:= trunc(AcX);
145.       m3D.Y:= trunc(AcY);
146.       m3D.Z:= trunc(AcZ);
147.    End;
148.

« Last Edit: May 24, 2022, 12:58:24 pm by Weitentaaal »
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### pixel_

• New Member
• Posts: 10
##### Re: Handle 3D Coordinates on a canvas
« Reply #1 on: June 11, 2022, 07:37:45 pm »
Hi. You can create one more TImage, make it not visible, paint every cell to different color r,g,b, create one or few arrays where this colors will saved, and then, when will click, by mouse x,y you can get color from invisible TImage, then find this color in array, index of color in array will equal index of cell.