Update utvclgraphics.tsf

加入3d旋转代码
This commit is contained in:
tslediter 2024-02-08 14:04:58 +08:00
parent b57770b81a
commit ae3f3b00f6
1 changed files with 336 additions and 0 deletions

View File

@ -2764,6 +2764,342 @@ type tg_const = class()
//////////////
end
implementation
type tg_3d_box = class()
function create();
begin
ftheta := 0;
falpha := 0;
f_changed := 0;
flinesindex := array(
(0,1),
(1,2),
(2,3),
(3,0),
(4,5),
(5,6),
(6,7),
(7,4),
(0,4),
(1,5),
(2,6),
(3,7)
);
fvectorsindex := array(
(0,1,2,3),
(0,4,7,3),
(0,1,5,4),
(1,5,6,2),
(2,6,7,3)//,
//(4,5,6,7),
);
fbounds := array(0,0,200,200);
fsizes := array(200,200,200);
frotemt := eye(3);
fvcenter := array(100,100,100);
fzoombounds := array((0,200),(0,200),(0,200));
//fvectors :=init_vecs(200,200,200) ;
faces := array();
FRates := array(1,1,1);
frevers := array(1,1,0);
end
function set_trans(t,a); //设置转换角度
begin
if (t=ftheta) and (falpha=a) then return ;
ftheta := t;
falpha := a;
c := cos(a);
s := sin(a);
c1 := cos(t);
s1 := sin(t);
frotemt := array((0,1,0),(1,0,0),(0,0,1)):*array((c,s,0),(-s,c,0),(0,0,1)):*array((1,0,0),(0,c1,s1),(0,-s1,c1));
//frotemt := array((1,0,0),(0,c1,s1),(0,-s1,c1)):*array((c,s,0),(-s,c,0),(0,0,1)):*array((0,1,0),(1,0,0),(0,0,1));
f_changed := true;
end
function refresh_box();//重算坐标框架
begin
if f_changed then
begin
f_changed := 0;
recalc_size();
end
end
function transxyz(x,y,z,_x,_y,_z); //旋转数据
begin
r := array((x,y,z)):*frotemt;
_x := r[0,0];
_y := r[0,1];
_z := r[0,2];
end
function untransxyz(x,y,z,_x,_y,_z);
begin
r := array((x,y,0)):/frotemt;
_x := r[0,0];
_y := r[0,1];
_z := r[0,2];
end
function zoom_to_xy(x,y,z,_x,_y,_z); //----------
begin
if frevers[0] then x0 := fsizes[0]/2-(x-fzoombounds[0,0])/FRates[0];
else
x0 := (x-fzoombounds[0,0])/FRates[0] -fsizes[0]/2;
if frevers[1] then y0 := fsizes[1]/2-(y-fzoombounds[1,0])/FRates[1];
else y0 := (y-fzoombounds[1,0])/FRates[1] -fsizes[1]/2;
if frevers[2] then z0 := fsizes[2]/2-(z-fzoombounds[2,0])/FRates[2];
else z0 := (z-fzoombounds[2,0])/FRates[2] -fsizes[2]/2;
transxyz(x0,y0,z0,x1,y1,_z);
x1 +=fvcenter[0];
y1 +=fvcenter[1];
_x := x1;
_y := y1;
end
property theta read ftheta;
property alpha read falpha;
property bounds read fbounds write set_bounds;
property zoombounds read gs_zoombounds write gs_zoombounds;
property size read get_size;
function paint_box(cvs);
begin
r := array();
cvs.pen.color := 0xff0000;
lines := array();
ps2 := array();
inpoints := array();
echo "\r\n>>>",(abs(ftheta/pi()) mod 2);
if (abs(ftheta/pi()) mod 2)=0 then
begin
for i:= 0 to 3 do
begin
if point_in_rgn(fvectors[4:7],fvectors[i]) then
begin
inpoints[length(inpoints)] := i;
end
end
end else
begin
for i:= 4 to 7 do
begin
if point_in_rgn(fvectors[0:3],fvectors[i]) then
begin
inpoints[length(inpoints)] := i;
end
end
end
hd := array();
for i,v in flinesindex do
begin
ps := fvectors[v];
if (inpoints intersect v) then hd[i] := true;
for j,vj in ps do
lines[i,j] := vj[0:1]+fvcenter;
//cvs.draw_polyline().points(ps1).draw();
end
for i,v in lines do
begin
ps1 := v;
if hd[i] then cvs.pen.style := 1;
else cvs.pen.style := 0;
cvs.draw_polyline().points(ps1).draw();
end
return ;
for i,v in fvectorsindex do
begin
ps := fvectors[v,0:1];
ps1 := array();
for j,vj in ps do
ps1[j] := vj+fvcenter;
ps1[j+1] := ps1[0];
cvs.draw_polyline().points(ps1).draw();
//break;
end
end
private
//////////长宽高////////////////////
fvcenter; //中心
//////////////////////
fvectorsindex; //定点次序
flinesindex;//
ftheta;
falpha;
frotemt;
fbounds;
f_changed;
fzoombounds;
fvectors;
FRates;
fsizes;
frevers;
private
function gs_zoombounds(idx,v); //小刻度线
begin
if ifarray(idx) then
begin
if ifarray(v) then
begin
for i,vi in idx do
begin
gs_zoombounds(vi,v[vi]);
end
end else
begin
r := array();
for i,vi in idx do
begin
return gs_zoombounds(vi);
end
end
end
if ifarray(v) and ifnumber(v[0]) and (v[0]<v[1]) then
begin
if idx in array(0,1,2) then
begin
fzoombounds[idx] := array(v[0],v[1]);
FRates[idx] := (v[1]-v[0])/fsizes[idx];
end
end else //get
begin
if idx in array(0,1,2) then return fzoombounds[idx];
return fzoombounds;
end
end
function set_bounds(v);
begin
if fbounds<>v then
begin
fbounds := v;
f_changed := true;
end
end
function get_size();
begin
return fsizes;
end
function get_new_w_h(w1,h1,w,h,z);
begin
z1 := (w1+h1)/2;
z := z1;
w := w1;
h := h1;
while true do
begin
ps := init_vecs(h,w,z);
bd := zeros(2,2);
for i,v in ps do
begin
transxyz(v[0],v[1],v[2],_x,_y,_z);
bd[0,0] := min(_x,bd[0,0]);
bd[0,1] := max(_x,bd[0,1]);
bd[1,0] := min(_y,bd[1,0]);
bd[1,1] := max(_y,bd[1,1]);
end
bw := bd[0,1]-bd[0,0];
bh := bd[1,1]-bd[1,0];
if bw<w1 and bh<h1 then break;
w*=0.99;
h*=0.99;
z*=0.99;
end
mj1 := w*h;
bk := array(w,h,z);
z := z1;
w := h1;
h := w1;
while true do
begin
ps := init_vecs(h,w,z);
bd := zeros(2,2);
for i,v in ps do
begin
transxyz(v[0],v[1],v[2],_x,_y,_z);
bd[0,0] := min(_x,bd[0,0]);
bd[0,1] := max(_x,bd[0,1]);
bd[1,0] := min(_y,bd[1,0]);
bd[1,1] := max(_y,bd[1,1]);
end
bw := bd[0,1]-bd[0,0];
bh := bd[1,1]-bd[1,0];
if bw<w1 and bh<h1 then break;
w*=0.99;
h*=0.99;
z*=0.99;
end
mj2 := w*h;
if mj2<mj1 then
begin
[w,h,z] := bk;
end
end
function recalc_size(); //重算大小
begin
w1 := fbounds[2]-fbounds[0];
h1 := fbounds[3]-fbounds[1];
fvcenter := array(fbounds[0]+w1/2,fbounds[1]+h1/2);
get_new_w_h(w1,h1,w,h,z);
fsizes[0] := h;
fsizes[1] := w;
fsizes[2] := z;
FRates[0] := (fzoombounds[0,1]-fzoombounds[0,0])/h;
FRates[1] := (fzoombounds[1,1]-fzoombounds[1,0])/w;
FRates[2] := (fzoombounds[2,1]-fzoombounds[2,0])/z;
fvectors := array();
for i,v in init_vecs(h,w,z) do
begin
transxyz(v[0],v[1],v[2],x,y,z);
fvectors[i] := array(x,y,z);
end
end
function init_vecs(x,y,z);
begin
r := array();
r[0]:=array(-x/2, -y/2, -z/2); //0
r[1]:=array(-x/2, y/2, -z/2); //1
r[2]:=array(x/2, y/2, -z/2); //2
r[3]:=array(x/2, -y/2, -z/2); //3
r[4]:=array(-x/2, -y/2, z/2); //4
r[5]:=array(-x/2, y/2, z/2); //5
r[6]:=array(x/2, y/2, z/2); //6
r[7]:=array(x/2, -y/2, z/2); //7
return r;
end
function point_in_rgn(rgn_,p);
begin
arg := 0;
rgn := rgn_ union array(rgn_[0]);
for i := 1 to length(rgn)-1 do
begin
p1 := rgn[i-1];
p2 := rgn[i];
v1 := array(p1[0]-p[0],p1[1]-p[1]);
v2 := array(p2[0]-p[0],p2[1]-p[1]);
argi := d2angle(v1,v2);
arg+=argi;
end
return (abs(arg/2-pi())<0.01);
end
function d2angle(v1,v2);
begin
return arccos(sum(v1*v2)/vectorsize(v1)/vectorsize(v2));
end
function vectorsize(v);
begin
return (v[0]^2+v[1]^2)^0.5;
end
end
function mg_bds(bds,d); //合并数据上下界
begin
d[0,0] := min(bds[0,0],d[0,0]);