Hallo, ich habe da ein 3D-Gitter und zwei Punkte P1 und P2, wodurch der Strahl verläuft und ich möchte, immer wenn der Strahl an einer Wand stößt, diese Koordinate inklusiver Angabe ob Wand bei X, Y oder Z, mitgeteilt bekommen.
Damit es einfacher ist, habe ich mal im Anhang eine Beispielgrafik, allerdings in 2D, angehängt.
Ich habe zwar schon ein Code, aber der ist
Grottenlangsam 
Hier der Code:
|
PHP-Quelltext
|
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
|
unit unitCollision;
interface
uses Math;
type float=extended;
type TPoint3D=record x,y,z:float;end;
type TPointCL=record x,y,z:float;ck:byte;end;
type TPoint3DArray=array of TPoint3D;
type TPointCLArray=array of TPointCL;
procedure CalculateCollision(var start,stop:TPoint3D;var output:TPointCLArray);
function QFrac(q:float):float;
function QInt(q:float):float;
function QSgn(q:float):shortint;
function ESgn(q:float):shortint;
function EqSgn(q,r:float):shortint;
function QFade(a,b:integer;c:byte):integer;
procedure QRotate(var x,y:float;r:float);
implementation
procedure CalculateCollision(var start,stop:TPoint3D;var output:TPointCLArray);
var i:integer;r:byte;
xs,ys,zs,q,qd:float;
xp,yp,zp:float;
qx,qy,qz:float;
p:TPointCL;
begin
if (Length(output)=0)then exit;
i:=0;
xs:=stop.x - start.x;
ys:=stop.y - start.y;
zs:=stop.z - start.z;
q:=0;
qd:=((Abs(xs)+Abs(ys)+Abs(zs))*1000);
if qd=0then qd:=1 else qd:=1/qd;
while i<length(output) do begin
q:=q+qd;
//Find grid position
xp:=start.x+xs*q;
yp:=start.y+ys*q;
zp:=start.z+zs*q;
if xs=0then qx:=high(integer)else qx:=(QInt(xp)+1*ESgn(xs)-start.x)/xs;
if ys=0then qy:=high(integer)else qy:=(QInt(yp)+1*ESgn(ys)-start.y)/ys;
if zs=0then qz:=high(integer)else qz:=(QInt(zp)+1*ESgn(zs)-start.z)/zs;
if(qx<=qy)and(qx<=qz)then begin
q:=qx;r:=1;
p.x:=start.x+xs*q;
p.y:=start.y+ys*q;
p.z:=start.z+zs*q;
p.ck:=r;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
if (Frac(p.y)=0) and (ys<>0) then begin
p.ck:=2;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
if (Frac(p.z)=0) and (zs<>0) then begin
p.ck:=3;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
Continue;
end;
if(qy<=qx)and(qy<=qz)then begin
q:=qy;r:=2;
p.x:=start.x+xs*q;
p.y:=start.y+ys*q;
p.z:=start.z+zs*q;
p.ck:=r;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
if (Frac(p.x)=0) and (xs<>0) then begin
p.ck:=1;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
if (Frac(p.z)=0) and (zs<>0) then begin
p.ck:=3;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
Continue;
end;
if(qz<=qx)and(qz<=qy)then begin
q:=qz;r:=3;
p.x:=start.x+xs*q;
p.y:=start.y+ys*q;
p.z:=start.z+zs*q;
p.ck:=r;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
if (Frac(p.x)=0) and (xs<>0) then begin
p.ck:=1;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
if (Frac(p.y)=0) and (ys<>0) then begin
p.ck:=2;output[i]:=p;Inc(i);
if i>=length(output) then Continue;
end;
Continue;
end;
end;
end;
function QFrac(q:float):float;
begin
if q>=0then result:=Frac(q)else result:=1-Frac(-q);
end;
function QInt(q:float):float;
begin
//if q>=0then result:=Floor(q)else result:=Ceil(q);
result:=abs(floor(q));
if q<0then result:=floor(-1-result);
end;
function QSgn(q:float):shortint;
begin
result:=0;
if q<0then result:=-1;
if q>0then result:=1;
end;
function ESgn(q:float):shortint;
begin
result:=0;
if q>=0then result:=1;
end;
function EqSgn(q,r:float):shortint;
begin
result:=0;
if q>=0then result:=1-result;
if r>=0then result:=1-result;
// if q>=0then result:=result or 1;
// if r>=0then result:=result or 1;
end;
function QFade(a,b:integer;c:byte):integer;
var r1,g1,b1,r2,g2,b2:byte;
begin
b1:=a shr 16; b2:=b shr 16;
g1:=a shr 8; g2:=b shr 8;
r1:=a; r2:=b;
b1:=(((b2-b1)*c)shr 8)+b1;
g1:=(((g2-g1)*c)shr 8)+g1;
r1:=(((r2-r1)*c)shr 8)+r1;
result:=r1+g1*256+b1*65536;
end;
procedure QRotate(var x,y:float;r:float);
var a,b:float;
begin
a:=x;b:=y;
x:=Cos(r)*a + Sin(r)*b;
y:=Cos(r)*b - Sin(r)*a;
end;
end.
|
Jemand eine Idee zur Optimierung?