Welcome to the first tutorial in our series on using vessel.js – a powerful JavaScript library that combines the principles of data-driven design with a web-based, object-oriented approach for conceptual ship design and simulation.
This first tutorial will show you how to create a simple 3D ship using the vessels.js library. After the tutorial you you'll be equipped with the knowledge to:
The process of inserting a typical ship into a digital scene can be divided into four steps: the import of the library, the load of the vessels.js JSON format, creating the 3D module, and the insertion on the ship.
// Importing the Library
import * as Vessel from "../build/vessel.module.js"
// Loading the Ship's Design JSON file
const ship = new Vessel.Ship("./blockCase.json")
// Creating the Ship3D module and adding it to a Scene
ship.createShip3D({
stlPath: "../examples/3D_models/STL/various",
}, Ship3D)
// scene object derived from the Three.js library
scene.add(ship.ship3D);
The Ship method points toward a JSON file that contains the vessel
information in the Vessel.js format. On JSON Format section
we will discuss more about the Vessel.js format. For this example the
blockCase.json file was initialized with the Vessel.Ship
method.
The scene object is part of the Three.js library and it is used for displaying the 3D visualization. For a detailed explanation of how scenes work, please refer to the main documentation at https://threejs.org/docs/#manual/en/introduction/Creating-a-scene.
The following visualization shows how should be the visualization for the scene (click and drag under the scene to control the orbit view):
Vessel.js employs a JSON format to store the design of the ship. On the previous example theblockCase.json was imported using Vessel.Ship
The JSON file is segmented into four sections, namely:
designState, structure, baseObjects and derivedObjects.
Presented here is a sample of a JSON file along with its data functions:
{
"designState": {
// Holds several parameters that affect calculations
},
"structure": {
// Definition of the hull, decks and bulkheads
},
"baseObjects": [
// Array of base objects as it is fetched from the provided specification.
// It groups several elements,
// for example (cargo holds, tanks, ballast tanks, etc.)
],
"derivedObjects": [
// Array of derived objects. A derived object is a base object
// with information added on top of it. Derived objects are classified
// as parts of baseObjects.
]
}
designState contains several parameters that affect the calculations
such as tank fillings. The object can be subdivided in two sections:
calculationParameters and objectOverrides.
Here is as simple example of a designState object format:
"designState": {
"calculationParameters": {
"LWL_design": 22.5,
"BWL": 10,
"Draft_design": 2,
"Cb_design": 1,
"speed": 12,
},
"objectOverrides": {
"derivedByGroup": {
"cargo tanks": {
"fullness": 0
},
"ballast tanks": {
"fullness": 1
}
}
}
},
The calculationParameters comprise a collection of
specified ship parameters used for calculations.
Certain parameters, such as LWL and Cb, can be calculated from
load and hull geometry, while others are uncertain or not covered by existing calculations.
For a full list of parameters information that can be stored
in this list please refer to the
Wiki (calculationParameters)
.
The objectOverrides assign state information to a specific set of base object groups.
This example shows a set of objects overrides for the "cargo tanks" and "ballast tanks".
For a full overview of the object overrides types please refer to the
Wiki (objectOverrides)
.
"structure": {
"hull": {
"attributes": {
"LOA": 22.5,
"BOA": 10,
"Depth": 2.5,
"APP": 0
},
"halfBreadths": {
"waterlines": [0, 0, 1],
"stations": [0, 1],
"table": [[0, 0], [1, 1], [1, 1]]
},
"buttockHeights": {},
"affiliations": {
"SBSD": "Hull",
"group": "structure"
}
},
"decks": {
"BallastTop": {
"zFloor": 0.4,
"thickness": 0.01,
"xAft": 0,
"xFwd": 22.5,
"yCentre": 0,
"breadth": 10,
"density": 7850,
"affiliations": {
"SBSD": "Hull",
"group": "structure"
}
}
},
"bulkheads": {
"AB": {
"xAft": 11.25,
"thickness": 0.01,
"density": 7850,
"affiliations": {
"SBSD": "Hull",
"group": "structure"
}
}
}
}
For a full explanation about the structure section
please refer to the tutorial in
https://observablehq.com/@icarofonseca/hull-definition-and-hydrostatics and
Wiki (Structure)
baseObjects and derivedObjects define different elements
of a ship such as equipment, tanks and compartments of the ship.
On the base object it is possible to group several object states into a single supergroup.
For instance, a cargo hold can be divided into several compartments, each one with a different state.
Here is an example for the baseObjects for a specific cargo hold type:
"baseObjects": [
{
"id": "cargo",
"affiliations": {},
"boxDimensions": {
"length": 10.25,
"breadth": 9,
"height": 1.6
},
"capabilities": {},
"baseState": {
"fullness": 0
},
"weightInformation": {
"contentDensity": 850,
"volumeCapacity": 145,
"lightweight": 10000,
"fullnessCGMapping": {
"fullnesses": [0, 0.25, 0.5, 0.75, 1],
"cgs": [
[0, 0, 0.8],
[0, 0, 0.347013783],
[0, 0, 0.455846422],
[0, 0, 0.6195241],
[0, 0, 0.8]
]
}
}
}]
This object can be connect to a specific derivedObjects
allowing the compartment to inherit the specifications from the
baseObjects group. Here is an example for a
so called a cargo "Tank1" derived tank:
"derivedObjects": [
{
"id": "Tank1",
"baseObject": "cargo",
"affiliations": {
"SBSD": "Liquid and dry bulk cargo",
"group": "cargo tanks",
"Deck": "CargoDeck",
"SFI": "102"
},
"referenceState": {
"xCentre": 16.875,
"yCentre": 0,
"zBase": 0.4
}
]
Note that the Tank1 will inherit the specifications from the cargo base object, containing
for example the same dimensions and weight information
(it will be a tank with 10.25 x 9 x 1.6 located at 16.875 x 0 x 0.4 m from the origin).
For further references on baseObjects and derivedObjects please refer to the
Wiki (BaseObject)
and
Wiki (DerivedObject)
.