platform.apilevel = "1.0" -- "How High" port from Java applet -- Author : Adriweb -- Thanks Levak and Jim Bauwens for the help -- 11/22/2011 -- Version 1.1 ---------------------------- --------- Globals ---------- ---------------------------- function reset() pouring = false slider = Slider() slider.position = 0 from=1 sliderspeed = 1 sliderlast = 0 sliderdir = 1 sliderammo = 0 end function on.resize(x,y) scrHgt = y scrWdth = x platform.window:invalidate() end on.resize() ---------------------------- --------- Events: ---------- ---------------------------- function on.charIn(ch) if ch == "1" then reset() fromShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, math.random(5,85), 100) toShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, 0, 100) slider.position = fromShape.filled elseif ch == "2" then reset() fromShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, math.random(5,85), 90) toShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, 0, 90) slider.position = fromShape.filled elseif ch == "3" then reset() fromShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, math.random(5,76), 77) toShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, 0, 77) slider.position = fromShape.filled elseif ch == "4" then reset() fromShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, math.random(5,76), 77) toShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, 0, 100) slider.position = fromShape.filled elseif ch == "5" then reset() fromShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, math.random(5,85), 100) toShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, 0, 77) slider.position = fromShape.filled elseif ch == "6" then reset() fromShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, math.random(5,76), 77) toShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, 0, 90) slider.position = fromShape.filled elseif ch == "7" then reset() fromShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, math.random(5,85), 90) toShape = Shape("coneCircle", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 1/3*3.1416*r*r*h end, 0, 77) slider.position = fromShape.filled elseif ch == "8" then reset() fromShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, math.random(5,85), 100) toShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, 0, 90) slider.position = fromShape.filled elseif ch == "9" then reset() fromShape = Shape("cylinder", {100, math.random(2,4)}, function(data) local h,r = unpack(data) return 3.1416*r*r*h end, math.random(5,85), 80) toShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, 0, 100) slider.position = fromShape.filled elseif ch == "+" then local time = timer.getMilliSecCounter() if sliderdir == 1 and time-sliderlast<400 then sliderspeed = sliderammo>5 and sliderspeed*1.25 or sliderspeed sliderammo = sliderammo+1 else sliderspeed = 1 sliderdir = 1 sliderammo = 0 end sliderlast = time slider.position = (slider.position < 400) and math.min(100, slider.position + math.floor(sliderspeed)) or slider.position elseif ch == "-" then local time = timer.getMilliSecCounter() if sliderdir == -1 and time-sliderlast<400 then sliderspeed = sliderammo>5 and sliderspeed*1.25 or sliderspeed sliderammo = sliderammo+1 else sliderspeed = 1 sliderdir = -1 sliderammo = 0 end sliderlast = time slider.position = (slider.position >= 1) and math.max(0,slider.position - math.floor(sliderspeed)) or slider.position end platform.window:invalidate() end function on.arrowUp() on.charIn("+") end function on.arrowDown() on.charIn("-") end function on.grabDown(x, y) if y>slider.y and yslider.x-0.2*scrWdth and xslider.y and yslider.x-0.2*scrWdth and xslider.y and yslider.x-0.2*scrWdth and x fromShape.startingFilled then fromShape.filled = fromShape.startingFilled end fromShape:paint(gc,0.3*scrWdth) toShape:paint(gc,0.7*scrWdth) slider:paint(gc, 0.61*scrWdth) end ---------------------------- ------- Shape Class -------- ---------------------------- Shape = class() function Shape:init(theType, data, formula, filled, overflow) self.theType = theType self.data = data self.colors = {math.random(0,255),math.random(0,255),math.random(0,255)} self.formula = math.floor(100*formula(self.data))*0.01 -- rounded self.filled = math.floor(100*filled)/100 -- this is out of 100 (95, actually) self.startingFilled = self.filled self.overflow = overflow self.formulaFunc = formula self.currData = copyTable(data) self.currData[1] = self.filled self.currentVol = math.floor(100*formula(self.currData))*0.01 -- rounded self.currData[1] = self.filled-1 local tmp = math.floor(100*self.formulaFunc(self.currData))*0.01 self.deltaVolforDelta = self.currentVol - tmp end function Shape:change(delta) if (from == -1 and fromShape.filled == 0 and toShape.filled + delta > fromShape.startingFilled) or (from == 1 and toShape.filled == 0 and fromShape.filled + delta > toShape.startingFilled) then pouring = false else if self.filled + delta >= 0 then self.filled = self.filled + delta else pouring = false end end end function Shape:paint(gc,x) gc:setColorRGB(0,0,0) if self.filled >= self.overflow then self.filled = self.overflow gc:setColorRGB(255,0,0) gc:drawString("Overflow !",scrWdth-90,2,"top") gc:setColorRGB(0,0,0) end if self.theType == "rect" then local n=math.floor(0.04*scrHgt+0.5) gc:drawRect(x+0.05*scrWdth,0.1*scrHgt+n,0.2*scrWdth-0.5,0.6*scrHgt-1) gc:drawLine(x,0.16*scrHgt+0.6*scrHgt-1+n,x+0.05*scrWdth,0.1*scrHgt+0.6*scrHgt+n) gc:drawString("Length : " .. self.data[3],x,0.75*scrHgt+n,"top") gc:drawString("Width : " .. self.data[2],x,0.75*scrHgt+15+n,"top") if self.filled > 0.5 then gc:setColorRGB(unpack(self.colors)) else gc:setColorRGB(255,255,255) end gc:fillPolygon({x,0.76*scrHgt-1+n, x+0.2*scrWdth-1,0.76*scrHgt-1+n, x-.5+0.2*scrWdth+0.05*scrWdth,0.7*scrHgt-1+n, x-.5+0.2*scrWdth+0.05*scrWdth,0.6*scrHgt*0.01*(117-self.filled)-1+n, x+0.05*scrWdth,0.6*scrHgt*0.01*(117-self.filled)-1+n, x,0.6*scrHgt*0.01*(117-self.filled)-1+0.06*scrHgt+n, }) gc:setColorRGB(140,140,140) gc:drawPolyLine({x,0.6*scrHgt*0.01*(117-self.filled)-1+0.06*scrHgt+n, x+0.2*scrWdth-2,0.6*scrHgt*0.01*(117-self.filled)-1+0.06*scrHgt+n, x+0.25*scrWdth-1,0.6*scrHgt*0.01*(117-self.filled)-1+n, x+0.25*scrWdth-1,0.6*scrHgt*0.01*(117-self.filled)-1+n, x+0.05*scrWdth,0.6*scrHgt*0.01*(117-self.filled)-1+n, x,0.6*scrHgt*0.01*(117-self.filled)-1+0.06*scrHgt+n, }) gc:setColorRGB(0,0,0) gc:drawRect(x,0.16*scrHgt+n,0.2*scrWdth,0.6*scrHgt) gc:drawLine(x+0.2*scrWdth-1,0.16*scrHgt+n,x+0.2*scrWdth-1+0.05*scrWdth,0.15*scrHgt-0.05*scrHgt+n) gc:drawLine(x,0.16*scrHgt+n,x+0.05*scrWdth,0.15*scrHgt-0.05*scrHgt+n) gc:drawLine(x+0.2*scrWdth-1,0.16*scrHgt+0.6*scrHgt-1+n,x+0.25*scrWdth-.5,0.7*scrHgt-1+n) elseif self.theType == "cylinder" then gc:drawArc(x,0.7*scrHgt,0.2*scrWdth,0.1*scrHgt,0,360) gc:drawLine(x,0.2*scrHgt,x,0.75*scrHgt) gc:drawLine(x+0.2*scrWdth-1,0.2*scrHgt,x+0.2*scrWdth-1,0.75*scrHgt) gc:drawString("Radius : " .. self.data[2],x,0.85*scrHgt,"top") gc:setColorRGB(unpack(self.colors)) if self.filled > 1 then gc:fillArc(x+1,0.75*scrHgt-0.6*scrHgt*0.01*self.filled-1-0.05*scrHgt,0.2*scrWdth-2,0.1*scrHgt,0,360) gc:fillRect(x+1,0.75*scrHgt-0.6*scrHgt*0.01*self.filled-1,0.2*scrWdth-1.5,0.6*scrHgt*0.01*self.filled) gc:fillArc(x+1,0.7*scrHgt,0.2*scrWdth-1,0.1*scrHgt,0,360) end gc:setColorRGB(0,0,0) gc:drawArc(x,0.15*scrHgt,0.2*scrWdth,0.1*scrHgt,0,360) gc:setColorRGB(140,140,140) if self.filled > 1 then gc:drawArc(x+1,0.75*scrHgt-0.6*scrHgt*0.01*self.filled-1-0.05*scrHgt,0.2*scrWdth-2,0.1*scrHgt,0,360) end elseif self.theType == "coneCircle" then gc:drawString("Radius : " .. self.data[2],x,0.85*scrHgt,"top") gc:setColorRGB(unpack(self.colors)) gc:fillPolygon({x+0.1*scrWdth, 0.8*scrHgt-1, (x+0.101*scrWdth)+(self.filled*0.42), (0.01*(105-self.filled))*0.74*scrHgt-1, (x+0.101*scrWdth)-(self.filled*0.42), (0.01*(105-self.filled))*0.74*scrHgt-1, }) gc:fillArc((x+0.101*scrWdth)-(self.filled*0.42),0.01*(105-self.filled)*0.74*scrHgt-5,0.21*scrWdth*0.0125*self.filled,0.05*scrHgt,0,180) gc:setColorRGB(140,140,140) gc:drawArc((x+0.101*scrWdth)-(self.filled*0.42),0.01*(105-self.filled)*0.74*scrHgt-5,0.21*scrWdth*0.012*self.filled,0.05*scrHgt,0,360) gc:setColorRGB(0,0,0) gc:drawLine(x, 0.2*scrHgt, x+0.1*scrWdth,0.8*scrHgt) gc:drawLine(x+0.2*scrWdth-1, 0.2*scrHgt, x+0.1*scrWdth,0.8*scrHgt) gc:drawArc(x,0.15*scrHgt,0.2*scrWdth,0.1*scrHgt,0,360) end gc:setColorRGB(0,0,0) --gc:drawString(self.theType,x+18,10,"top") -- gc:drawString(math.floor(self.filled+0.5),x+18,0,"top") self.currData = copyTable(self.data) self.currData[1] = self.filled self.currentVol = math.floor(100*self.formulaFunc(self.currData))*0.01 self.currData[1] = self.filled-1 if self.theType == "coneCircle" then self.currData[2] = self.currData[2]-self.currData[2]/100 end local tmp = math.floor(100*self.formulaFunc(self.currData))*0.01 self.deltaVolforDelta = self.currentVol - tmp end function Shape:getDelta(other, fromDelta) if self.theType == other.theType and (self.formula == other.formula) then return 1 end if self.theType == "rect" then return other.deltaVolforDelta/(self.data[2]*self.data[3]) elseif self.theType == "cylinder" then return other.deltaVolforDelta/(self.data[2]*self.data[2]*3.1416) elseif self.theType == "coneCircle" then return 3*other.deltaVolforDelta/(self.data[2]*self.data[2]*3.1416) end return 1 end function Shape:getFinalVolume(other) return other.formula/self.formula --- faux, mais j'ai plus le temps ... A faire avec un nSolve... end ---------------------------- ------- Slider Class ------- ---------------------------- Slider = class() function Slider:init() self.position = 25 end function Slider:paint(gc, x) local sliderw = 4 local sliderh = 0.6*scrHgt + sliderw local slidery = 0.2*scrHgt - sliderw/2 -1 local sliderx = x local sliderp = (100-self.position) * (sliderh - sliderw)/100 self.y = slidery self.h = sliderh self.x = x gc:drawArc(sliderx-6, slidery+sliderh-6, 16, 8, 0, 360) gc:setColorRGB(180,180,180) gc:fillArc(sliderx-6, slidery+sliderh-6, 16, 8, 0, 360) gc:fillRect(sliderx, slidery, sliderw, sliderh) gc:setColorRGB(0,0,0) gc:drawRect(sliderx, slidery, sliderw, sliderh) local label = tostring(self.position)--/10) local labes = gc:getStringWidth(label) gc:setColorRGB(255,255,255) gc:fillRect(sliderx-11, slidery+sliderp-17, 26, 15) gc:setColorRGB(0,0,0) gc:drawRect(sliderx-12, slidery+sliderp-18, 26, 16) gc:drawString(label, sliderx - labes*.5 + 1, slidery+sliderp) gc:fillRect(sliderx-scrWdth*0.20, slidery+sliderp + sliderw/2, scrWdth*0.40+sliderw,1) gc:drawRect(sliderx-1, slidery+sliderp, sliderw+2, sliderw) end ---------------------------- ------Other functions:------ ---------------------------- function copyTable(t) local t2 = {} for k,v in pairs(t) do t2[k] = v end return t2 end -- default shapes fromShape = Shape("rect", {100, math.random(2,3), math.random(2,5)},function(data) local h, wd, len = unpack(data) return wd*len*h end, math.random(5,85), 100) toShape = Shape("rect", {100, math.random(2,3), math.random(2,5)}, function(data) local h, wd, len = unpack(data) return wd*len*h end, 0, 100) reset() slider.position = fromShape.filled