开发者

How can I include all eventualities?

This code takes in a 3array (position) and tests to see whether it sits in some region of the model or not. The problem is in the PbSheild method, I can't work out why though. This code will work as is (well it will not work as is, that's the point).

class Geometry                    

$polyCylRad = 2.5                       
$polyCylFr = 15                         
$polyCylB = -2.0                          
$borPolyBoxL = 9.0 / 2
$pbCylRad = 3.0 
$pbBoxL = 10.0 / 2
$cdBoxL = 9.5 / 2
$xSquared = Float
$ySquared = Float
$zSquared = Float
$modX = Float
$modY = Float
$modZ =Float
$position = Array.new


def checkMaterial(params)

  $position = params
  $xSquared = $position[0] ** 2
  $ySquared = $position[1] ** 2
  $zSquared = $position[2] ** 2
  $modX = Math.sqrt($xSquared)
  $modY = Math.sqrt($ySquared)
  $modZ = Math.sqrt($zSquared)

  puts "polyCyl: " + self.polyCylinder.to_s
  puts "borpoly: " + self.borPolyBox.to_s
  puts "Cd: " + self.CdShield.to_s
  puts "Pb Cylinder: " + self.PbCylinder.to_s
  puts "Pb: " + self.PbShield.to_s
  puts "FreeSpace: " + self.FreeSpace.to_s

  material
end

def polyCylinder
  Math.sqrt($ySquared + $zSquared) <= $polyCylRad && $position[0] >= $polyCylB && $position[0] <= $polyCylFr
end

def borPolyBox
  !polyCylinder && ($modX <= $borPolyBoxL || $modY <= $borPolyBoxL || $modZ <= borPolyBoxL) && !($modX > $borPolyBoxL || $modY > $borPolyBoxL || $modZ > borPolyBoxL)
end

def CdShield
  !polyCylinder && !borPolyBox && ($modX <= $cdBoxL || $modY <= $cdBoxL || $modZ <= $cdBoxL) &&  !($modX > $cdBoxL || $modY > $cdBoxL || $modZ > $cdBoxL)
end

def PbCylinder
  !polyCylinder && $position[0] >= $cdBoxL && $position[0]  <= $polyCylFr && Math.sqrt($ySquared + zSquared) <= $pbCylRad
end 

def PbShield
  !polyCylinder && !borPolyBox && !CdShield && !PbCylinder && ($modX <=开发者_如何学JAVA $pbBoxL || $modY <= $pbBoxL || $modZ <= $pbBoxL) && !($modX > $pbBoxL || $modY > $pbBoxL || $modZ > $pbBoxL)                                                  
end

def FreeSpace
  !polyCylinder && !borPolyBox && !CdShield && !PbShield && !PbCylinder
end

def material
  [
  [:polyCylinder, 'poly'],
  [:borPolyBox, 'borPoly'],
  [:CdShield, 'Cd'],
  [:PbCylinder, 'Pb'],
  [:PbShield, 'Pb'],
  [:FreeSpace, 'air']
  ].each do |method, name|
  return name if send(method)
              end
  false
end

end

$bob = Geometry.new
posVect = Array.new
posVect << 0 << 0 << 0
$bob.checkMaterial(posVect)

while posVect[0]  < 25 do

$bob.checkMaterial(posVect)
puts "Xpos: " + posVect[0].to_s
puts "Ypos: " + posVect[1].to_s
puts "Zpos: " + posVect[2].to_s
puts "polyCyl: " + $bob.polyCylinder.to_s
puts "borpoly: " + $bob.borPolyBox.to_s
puts "Cd: " + $bob.CdShield.to_s
puts "Pb: " + $bob.PbShield.to_s
puts "FreeSpace: " + $bob.FreeSpace.to_s
puts ""

posVect[0] += 1

end

If you think this looks suspiciously like it is related to my c++ code you are correct, am writing two structurally different monte carlo's in Ruby and c++ (learning Ruby and the deepening c++ knowledge at the same time).

Thanks!


I would rewrite this entirely. You have a couple of problems that you want to solve. First, you want to define a region and see if a point is within that region. That should probably be one module with a method for defining regions and a method for placing a point within a defined region. You could, if you wished, define the regions in the module itself, or define them on the fly, whichever. That would give you the ability to pass a region name or definition and a point to a single method and get back whether the point is within that region. That would be much easier to test.

Second, you want to determine the material value: true or false, for every material. You might consider using a case statement for this. You write a method that returns values for your region test (like :poly, :box, whatever) and then use that as the test for your case statement:

   case whatever(point)
   when (:foo)
     set some values
   when (:bar)
     set some other values
   end

If you set the default for every material value to false (a good plan) then you'll only have to update the trues, and it should be easy, based on the return value of your region check method, to decide what values need to be true or can be true.

Breaking the code apart this way--or some other way--will make it much easier to test.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜