GOSUB DefFn nx=7 %columns ny=7 %rows ARRAY.LOAD box[],0,0,0,(nx-1)*100,(nx/2)*100,(ny-1)*100 GR.open 255,0,0,0,0,1 GR.SCREEN sx,sy !Viewers position ARRAY.LOAD vp[],(nx-1)*50,800,-2000 !Light position ARRAY.LOAD lp[],-1500,5000,-1500 !screen plane !idx 1-3 point on plane !idx 4-6 vector perpendicular to plane should be 0,0,1 ARRAY.LOAD sp[],0,0,-50,0,0,1 DIM ip[3] %intersection point DIM l[6] %line LIST.CREATE n,lsel %selected points LIST.CREATE n,lgos %gr.obj. sel. p. !the view pos is a point on the line l[1]=vp[1] l[2]=vp[2] l[3]=vp[3] !all the points 3d DIM px[nx*ny+8] DIM py[nx*ny+8] DIM pz[nx*ny+8] !points on screen 2d DIM px1[nx*ny+8] DIM py1[nx*ny+8] !corners of the box px[nx*ny+1]=box[1] py[nx*ny+1]=box[2] pz[nx*ny+1]=box[3] px[nx*ny+2]=box[4] % py[nx*ny+2]=box[2] % pz[nx*ny+2]=box[3] % px[nx*ny+3]=box[4] py[nx*ny+3]=box[5] pz[nx*ny+3]=box[3] px[nx*ny+4]=box[1] % py[nx*ny+4]=box[5] % pz[nx*ny+4]=box[3] % px[nx*ny+5]=box[1] py[nx*ny+5]=box[2] pz[nx*ny+5]=box[6] px[nx*ny+6]=box[4] % py[nx*ny+6]=box[2] % pz[nx*ny+6]=box[6] % px[nx*ny+7]=box[4] py[nx*ny+7]=box[5] pz[nx*ny+7]=box[6] px[nx*ny+8]=box[1] % py[nx*ny+8]=box[5] % pz[nx*ny+8]=box[6] % !points: FOR i=0 TO nx-1 FOR j=0 TO ny-1 idx=i+j*nx+1 px[idx]=i*100 py[idx]=0 pz[idx]=(ny-j-1)*100 NEXT j NEXT i !List of triangles: LIST.CREATE n,llta !box of=nx*ny !One triangle LIST.CREATE n,lta LIST.ADD lta,of+1,of+2,of+3 LIST.ADD llta,lta !and so on LIST.CREATE n,lta LIST.ADD lta,of+3,of+4,of+1 LIST.ADD llta,lta LIST.CREATE n,lta LIST.ADD lta,of+1,of+5,of+6 LIST.ADD llta,lta LIST.CREATE n,lta LIST.ADD lta,of+2,of+6,of+7 LIST.ADD llta,lta LIST.CREATE n,lta LIST.ADD lta,of+3,of+7,of+8 LIST.ADD llta,lta LIST.CREATE n,lta LIST.ADD lta,of+4,of+8,of+5 LIST.ADD llta,lta !Surface ... more triangles FOR j=0 TO ny-2 FOR i=0 TO nx-2 pn1=i+j*nx+1 pn2=i+(j+1)*nx+1 pn3=i+j*nx+2 LIST.CREATE n,lta LIST.ADD lta,pn1,pn2,pn3 LIST.ADD llta,lta pn1=pn2 pn2=i+(j+1)*nx+2 LIST.CREATE n,lta LIST.ADD lta,pn1,pn2,pn3 LIST.ADD llta,lta NEXT i NEXT j ! render DO GR.CLS GR.COLOR 255,255,255,255,1 !project all points on screen !and find min & max values xmi=1000000 ymi=1000000 xma=-1000000 yma=-1000000 FOR i=1 TO nx*ny+8 l[4]=px[i]-vp[1] l[5]=py[i]-vp[2] l[6]=pz[i]-vp[3] intersectLP(l[],sp[],ip[]) px1[i]=ip[1] py1[i]=-ip[2] !ignore pz IF px1[i]xma THEN xma=px1[i] ENDIF IF py1[i]yma THEN yma=py1[i] ENDIF NEXT i !which is the limiting direction? rats=sx/sy %ratio screen !ratio data ratd=(xma-xmi)/(yma-ymi) !factor for scaling IF rats(c+200) THEN !more than 200ms from touch IF ABS(tx-stx)>100 THEN !moving in x direction !get the y value from input LIST.SIZE lsel,n INPUT "enter height",h !set the height of all selected points FOR i=1 TO n LIST.GET lsel,i,pos IF pos>0 THEN py[pos]=h ENDIF NEXT i !new calculation D_U.BREAK ENDIF !moving in y direction LIST.SIZE lsel,n FOR i=1 TO n LIST.GET lsel,i,pos IF pos>0 THEN !take the first selected point x=px1[pos] y=py1[pos] !show the point GR.MODIFY gocy,"x1",x-100,"y1",y,"x2",x+100,"y2",y GR.MODIFY goc1,"x1",x-100,"y1",y,"x2",x+100,"y2",y GR.MODIFY goc2,"x1",x,"y1",y-100,"x2",x,"y2",y+100 F_N.BREAK ENDIF NEXT i IF pos>0 THEN !a point is selected !show the new position !calculated by projection y2=py[pos]+(sty-ty) l[4]=px[pos]-vp[1] l[5]=py[pos]-vp[2]+(sty-ty) l[6]=pz[pos]-vp[3] intersectLP(l[],sp[],ip[]) y=-ip[2] GR.MODIFY gocy,"y1",y,"y2",y GR.MODIFY got1,"x",x-100,"y",y,"text",USING$("","%5.1f",y2) GR.MODIFY got2,"x",x+100,"y",y,"text",USING$("","%5.1f",y2) ENDIF GR.RENDER ENDIF ELSEIF !tt&ott THEN !finger released IF CLOCK()<(c+200) THEN !faster than 200ms x=px1[pos] y=py1[pos] LIST.SIZE lsel,n pos0=0 found=0 FOR i=1 TO n LIST.GET lsel,i,pos2 IF pos2=pos THEN !the point is selected, !cancel the selection LIST.REPLACE lsel,i,0 LIST.GET lgos,i,gos GR.MODIFY gos,"alpha",0 found=1 ELSEIF (pos2=0)&(pos0=0) THEN !found a gap in the list !remember the position pos0=i ENDIF NEXT i IF found=0 THEN !the point is not selected IF pos0=0 THEN !and there is no gap in the list !add the point to the selection LIST.ADD lsel,pos !and show it GR.COLOR 255,0,0,255,1 GR.CIRCLE vd,x,y,5 LIST.ADD lgos,vd ELSE !use the gap to remember the point LIST.REPLACE lsel,pos0,pos !and change the old indicator LIST.GET lgos,pos0,gos GR.MODIFY gos,"x",x,"y",y,"alpha",255 ENDIF ENDIF GR.RENDER ELSE !longer than 200ms !add difference to the height !of all selectet points LIST.SIZE lsel,n FOR i=1 TO n LIST.GET lsel,i,pos IF pos>0 THEN py[pos]+=(sty-ty) ENDIF NEXT i !and calculate again go=1 ENDIF ENDIF ott=tt PAUSE 10 UNTIL go UNTIL 0 END ! fn deffn: FN.DEF IntersectLP(l[],p[],ip[]) !Intersection line plane !Line: Array l[6] !1-3: Position vector, !4-6: Direction vector !Plane: Array p[6] !1-3: Position vector, !4-6: Direction vector perpendicular to plane !Result intersection: !Array ip[3] !The direction vectors must !be normalized, therefore ldx=l[4]:ldy=l[5]:ldz=l[6] dl=SQR(ldx*ldx+ldy*ldy+ldz*ldz) ldx/=dl:ldy/=dl:ldz/=dl !1. perpendicular to the normal of the plane ! set one value to 0, swap the other two and change the sign in one IF p[4]=0 THEN pd1x=0:pd1y=p[6]:pd1z=-p[5] ELSEIF p[5]=0 THEN pd1x=p[6]:pd1y=0:pd1z=-p[4] ELSE pd1x=p[5]:pd1y=-p[4]:pd1z=0 ENDIF !normalize the 1. perpendicular dl=SQR(pd1x*pd1x+pd1y*pd1y+pd1z*pd1z) pd1x/=dl:pd1y/=dl:pd1z/=dl !2. perpendicular to the normal of the plane and 1. perpendicular (vector product) pd2x=p[5]*pd1z-p[6]*pd1y pd2y=p[4]*pd1z-p[6]*pd1x pd2z=p[4]*pd1y-p[5]*pd1x !normalize the 2. perpendicular dl=SQR(pd2x*pd2x+pd2y*pd2y+pd2z*pd2z) pd2x/=dl:pd2y/=dl:pd2z/=dl !Calculate parameter a !for line=Pv-a*Dv !Determinants d1=(l[1]-p[1])*pd1y*pd2z+pd1x*pd2y*(l[3]-p[3])+pd2x*(l[2]-p[2])*pd1z- pd2x*pd1y*(l[3]-p[3])-pd1x*(l[2]-p[2])*pd2z-(l[1]-p[1])*pd2y*pd1z d2=ldx*pd1y*pd2z+pd1x*pd2y*ldz+pd2x*ldy*pd1z- pd2x*pd1y*ldz-pd1x*ldy*pd2z-ldx*pd2y*pd1z a=d1/d2 !Intersection on the line: ip[1]=l[1]-ldx*a ip[2]=l[2]-ldy*a ip[3]=l[3]-ldz*a FN.RTN 1 FN.END RETURN