require"SvgWriter"require"vmath"localimageWidth,imageHeight=500,500;localyAngle=math.rad(45);localzAngle=math.rad(20);localySin,yCos=math.sin(yAngle),math.cos(yAngle);localzSin,zCos=math.sin(zAngle),math.cos(zAngle);localyMat=vmath.mat4(vmath.vec4(yCos,0,ySin,0),vmath.vec4(0,1,0,0),vmath.vec4(-ySin,0,yCos,0),vmath.vec4(0,0,0,1))localzMat=vmath.mat4(vmath.vec4(1,0,0,0),vmath.vec4(0,zCos,-zSin,0),vmath.vec4(0,zSin,zCos,0),vmath.vec4(0,0,0,1))localworldScale=0.1;localscalingMatrix=vmath.mat4(vmath.vec4(worldScale,0,0,0),vmath.vec4(0,worldScale,0,0),vmath.vec4(0,0,worldScale,0),vmath.vec4(0,0,0,1))localfullMat=(scalingMatrix*zMat)*yMatlocalfunctionLocalTransform(listOfPoints)localret={};fori,pointinipairs(listOfPoints)doret[#ret+1]=fullMat:Transform(point);endreturnret;endlocalviewportMatrix=vmath.mat4(vmath.vec4(imageWidth/2,0,0,imageWidth/2),vmath.vec4(0,imageHeight/2,0,imageHeight/2),vmath.vec4(0,0,1,0),vmath.vec4(0,0,0,1))localfunctionViewportTransform(listOfPoints)localret={};fori,pointinipairs(listOfPoints)doret[#ret+1]=vmath.vec2(viewportMatrix:Transform(point));endreturnret;endlocalinitialBoxPoints={vmath.vec3(4.0,4.0,5.0),vmath.vec3(-4.0,4.0,5.0),vmath.vec3(4.0,-4.0,5.0),vmath.vec3(-4.0,-4.0,5.0),vmath.vec3(1.0,1.0,-5.0),vmath.vec3(-1.0,1.0,-5.0),vmath.vec3(1.0,-1.0,-5.0),vmath.vec3(-1.0,-1.0,-5.0),}localinitialAxisPoints={vmath.vec3(2.5,0.0,0.0),vmath.vec3(10.0,0.0,0.0),vmath.vec3(-2.5,0.0,0.0),vmath.vec3(-10.0,0.0,0.0),vmath.vec3(0.0,2.5,0.0),vmath.vec3(0.0,10.0,0.0),vmath.vec3(0.0,-2.5,0.0),vmath.vec3(0.0,-10.0,0.0),vmath.vec3(0.0,0.0,5.0),vmath.vec3(0.0,0.0,10.0),vmath.vec3(0.0,0.0,-5.0),vmath.vec3(0.0,0.0,-10.0),}localboxPoints=ViewportTransform(LocalTransform(initialBoxPoints));localaxisPoints=ViewportTransform(LocalTransform(initialAxisPoints));localboxIndexList={{2,4,8,6},{1,2,6,5},{1,2,4,3},{1,3,7,5},{3,4,8,7},{5,6,8,7},}localboxList={}fori,boxinipairs(boxIndexList)doboxList[i]={boxPoints[box[1]],boxPoints[box[2]],boxPoints[box[3]],boxPoints[box[4]]}endlocalstyleLib=SvgWriter.StyleLibrary();styleLib:AddStyle(nil,"black",SvgWriter.Style():stroke("black"):stroke_width("1px"));styleLib:AddStyle(nil,"dashed",SvgWriter.Style():stroke_dasharray({3,3}));styleLib:AddStyle(nil,"fill_black",SvgWriter.Style():fill("black"));styleLib:AddStyle(nil,"fill_transluscent",SvgWriter.Style():fill("blue"):fill_opacity(0.1));styleLib:AddStyle(nil,"arrowended",SvgWriter.Style():marker_end(SvgWriter.uriLocalElement("arrowhead")));localarrowheadPath=SvgWriter.Path();arrowheadPath:M{10,4}:L{0,0}:L{0,8}:Z();localwriter=SvgWriter.SvgWriter("ViewFrustum.svg",{imageWidth.."px",imageHeight.."px"},true);writer:StyleLibrary(styleLib);writer:BeginDefinitions();writer:BeginMarker({10,8},{10,4},"auto",nil,nil,"arrowhead");writer:Path(arrowheadPath,"black");writer:EndMarker();writer:EndDefinitions();--Draw the rear-most lines, with markers.writer:Line(axisPoints[3],axisPoints[4],{"black","arrowended"});writer:Line(axisPoints[7],axisPoints[8],{"black","arrowended"});writer:Line(axisPoints[9],axisPoints[10],{"black","arrowended"});--Draw the rear-most box sides.writer:Polygon(boxList[1],{"black","fill_transluscent"});writer:Polygon(boxList[2],{"black","fill_transluscent"});writer:Polygon(boxList[3],{"black","fill_transluscent"});--Draw the internal lines, no markers.writer:Line(axisPoints[1],axisPoints[3],{"black","dashed"});writer:Line(axisPoints[5],axisPoints[7],{"black","dashed"});writer:Line(axisPoints[9],axisPoints[11],{"black","dashed"});--Draw the front-most boxes.writer:Polygon(boxList[4],{"black","fill_transluscent"});writer:Polygon(boxList[5],{"black","fill_transluscent"});writer:Polygon(boxList[6],{"black","fill_transluscent"});--Draw the front-most lines, with markers.writer:Line(axisPoints[1],axisPoints[2],{"black","arrowended"});writer:Line(axisPoints[5],axisPoints[6],{"black","arrowended"});writer:Line(axisPoints[11],axisPoints[12],{"black","arrowended"});writer:Close();