Moved transversal areas ploter to new paradigm

This commit is contained in:
Jose Luis Cercós pita 2012-06-11 20:03:16 +02:00
parent 4026554d4e
commit ceae465c6c
2 changed files with 156 additions and 8 deletions

View File

@ -45,11 +45,15 @@ class TaskPanel:
return False
self.save()
# Plot data
data = Hydrostatics.Displacement(self.ship,self.form.draft.value(),self.form.trim.value())
x = self.ship.xSection[:]
y = data[0]
disp = data[1]
xcb = data[2]
data = Hydrostatics.displacement(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
disp = data[0]
xcb = data[1].x
data = Hydrostatics.areas(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
x = []
y = []
for i in range(0,len(data)):
x.append(data[i][0])
y.append(data[i][1])
Plot.Plot(x,y,disp,xcb, self.ship)
self.preview.clean()
return True
@ -194,7 +198,7 @@ class TaskPanel:
if draftFP < 0.0:
draftFP = 0.0
# Calculate hydrostatics involved
data = Hydrostatics.Displacement(self.ship,self.form.draft.value(),self.form.trim.value())
data = Hydrostatics.displacement(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
# Prepare the string in html format
string = 'L = %g [m]<BR>' % (self.ship.Length)
string = string + 'B = %g [m]<BR>' % (self.ship.Beam)
@ -202,8 +206,8 @@ class TaskPanel:
string = string + 'Trim = %g [degrees]<BR>' % (self.form.trim.value())
string = string + 'T<sub>AP</sub> = %g [m]<BR>' % (draftAP)
string = string + 'T<sub>FP</sub> = %g [m]<HR>' % (draftFP)
string = string + Translator.translate('Displacement') + ' = %g [ton]<BR>' % (data[1])
string = string + 'XCB = %g [m]' % (data[2])
string = string + Translator.translate('Displacement') + ' = %g [ton]<BR>' % (data[0])
string = string + 'XCB = %g [m]' % (data[1].x)
# Set the document
self.form.output.setHtml(string)

View File

@ -23,12 +23,156 @@
import math
# FreeCAD modules
from FreeCAD import Vector, Part
import FreeCAD as App
import FreeCADGui as Gui
# Module
import Instance
from shipUtils import Math
def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
""" Compute ship transversal areas.
@param ship Ship instance.
@param draft Ship draft.
@param roll Ship roll angle.
@param trim Ship trim angle.
@param yaw Ship yaw angle. Ussually you don't want to use this
value.
@param n Number of sections to perform.
@return Transversal areas (every area value is composed by x
coordinate and computed area)
"""
if n < 2:
return []
# We will take a duplicate of ship shape in order to place it
shape = ship.Shape.copy()
shape.translate(Vector(0.0,0.0,-draft))
# Rotations composition is Roll->Trim->Yaw
shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,0.0,1.0), yaw)
# Now we need to know the x range of values
bbox = shape.BoundBox
xmin = bbox.XMin
xmax = bbox.XMax
dx = (xmax - xmin) / (n-1.0)
# First area is equal to zero.
areas = [[xmin, 0.0]]
# Since we need face entities, in order to compute sections we will
# create boxes with front face at transversal area position,
# compute solid common, divide by faces, and preserve only desired
# ones.
App.Console.PrintMessage("Computing transversal areas...\n")
App.Console.PrintMessage("Some Inventor representation errors can be shown, ignore it please.\n")
for i in range(1,n-1):
App.Console.PrintMessage("%d / %d\n" % (i, n-2))
x = xmin + i*dx
area = 0.0
# Create the box
L = xmax - xmin
B = bbox.YMax - bbox.YMin
p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin + 1.0, p)
# Compute common part with ship
for s in shape.Solids:
# Get solids intersection
try:
common = box.common(s)
except:
continue
if common.Volume == 0.0:
continue
# Recompute object adding it to the scene, when we have
# computed desired data we can remove it.
try:
Part.show(common)
except:
continue
# Divide by faces and compute only section placed ones
faces = common.Faces
for f in faces:
faceBounds = f.BoundBox
# Orientation filter
if faceBounds.XMax - faceBounds.XMin > 0.00001:
continue
# Place filter
if abs(faceBounds.XMax - x) > 0.00001:
continue
# Valid face, compute area
area = area + f.Area
# Destroy last object generated
App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
# Append transversal area
areas.append([x, area])
# Last area is equal to zero
areas.append([xmax, 0.0])
App.Console.PrintMessage("Done!\n")
return areas
def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
""" Compute ship displacement.
@param ship Ship instance.
@param draft Ship draft.
@param roll Ship roll angle.
@param trim Ship trim angle.
@param yaw Ship yaw angle. Ussually you don't want to use this
value.
@return [disp, B, Cb], \n
disp = Ship displacement [ton].
B = Bouyance center [m].
Cb = Block coefficient.
@note Bouyance center will returned as FreeCAD.Vector class.
@note Returned Bouyance center is in non modified ship coordinates
"""
# We will take a duplicate of ship shape in order to place it
shape = ship.Shape.copy()
shape.translate(Vector(0.0,0.0,-draft))
# Rotations composition is Roll->Trim->Yaw
shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,0.0,1.0), yaw)
# Now we need to know box dimensions
bbox = shape.BoundBox
xmin = bbox.XMin
xmax = bbox.XMax
# Create the box
L = xmax - xmin
B = bbox.YMax - bbox.YMin
p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
box = Part.makeBox(3.0*L, 3.0*B, -bbox.ZMin + 1.0, p)
# Compute common part with ship
try:
common = box.common(shape)
except:
return [0.0, Vector(), 0.0]
# Get data
vol = common.Volume
cog = Vector()
for s in common.Solids:
sCoG = s.CenterOfMass
cog.x = cog.x + sCoG.x*s.Volume
cog.y = cog.y + sCoG.y*s.Volume
cog.z = cog.z + sCoG.z*s.Volume
cog.x = cog.x / vol
cog.y = cog.y / vol
cog.z = cog.z / vol
Vol = L*B*abs(bbox.ZMin)
# Undo transformations
B = Vector()
B.x = cog.x*math.cos(math.radians(-yaw)) - cog.y*math.sin(math.radians(-yaw))
B.y = cog.x*math.sin(math.radians(-yaw)) + cog.y*math.cos(math.radians(-yaw))
B.z = cog.z
cog.x = B.x*math.cos(math.radians(-trim)) - B.z*math.sin(math.radians(-trim))
cog.y = B.y
cog.z = B.x*math.sin(math.radians(-trim)) + B.z*math.cos(math.radians(-trim))
B.x = cog.x
B.y = cog.y*math.cos(math.radians(-roll)) - cog.z*math.sin(math.radians(-roll))
B.z = cog.y*math.sin(math.radians(-roll)) + cog.z*math.cos(math.radians(-roll))
B.z = B.z + draft
# Return data
dens = 1.025 # [tons/m3], salt water
return [dens*vol, B, vol/Vol]
def convertSection(section, x, z):
""" Transform linear points distribution of full section
into double list, where points are gropued by height, and