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 <= $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!

Answers


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.


Need Your Help

Perl - How create method alias in child class?

perl class

I'm trying to create an alias to a super class generic method in the child class, but it doesn't seem to work. This trick inside the same class works, but it doesn't seem to work across the super/...

How can I create a custom View with a Relative Size?

android view relative

I would like to design an application which could work with devices of any screen resolution.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.