# Build a House from a Floorplan

## Recommended Posts

Question is regarding example https://www.babylonjs-playground.com/#4GBWI5.

I don't understand how outer walls and footprint is created. I'm confused with the below code and can anyone please explain the below code step by step?

Thanks

``````for(var w = 0; w <= nbWalls; w++)
{
angle = Math.acos(BABYLON.Vector3.Dot(line, nextLine)/(line.length() * nextLine.length()));
direction = BABYLON.Vector3.Cross(nextLine, line).normalize().y;
lineNormal = new BABYLON.Vector3(line.z, 0, -1 * line.x).normalize();
line.normalize();
outerData[(w + 1) % nbWalls] = walls[(w + 1) % nbWalls].corner.add(lineNormal.scale(ply)).add(line.scale(direction * ply/Math.tan(angle/2)));
line = nextLine.clone();
walls[(w + 3) % nbWalls].corner.subtractToRef(walls[(w + 2) % nbWalls].corner, nextLine);
}``````

##### Share on other sites

In this image the blue walls are the inner walls and the red ones the outer walls, the position vectors ai, bi, ci are known and hence so will line L = bi - ai and next line N = ci - bi. We need to find the position vector of bo.  Knowing the distance between the inner and outer wall we can use the right angled triangles (as shown) to determine bo.

Using the vector dot product

``angle = Math.acos(BABYLON.Vector3.Dot(line, nextLine)/(line.length() * nextLine.length()));``

we can determine the angle between L and N. However that angle can be acute (left hand image), obtuse or reflex (right hand image) whereas the Math.acos returns an angle between 0 and PI.

Using the cross product

``direction = BABYLON.Vector3.Cross(nextLine, line).normalize().y;``

will give a vector perpendicular to L and N ie of the form (0, y, 0) and normalizing will give (0, 1, 0) or (0, -1, 0) depending whether the angle is reflex or not.

We need to find out the unit vector perpendicular to L (forms the right angle in the images).  Since taking the dot product of (x1, y1, z1) with (x2, y2, z2) gives x1x2 + y1y2 + z1z2 which will be zero when the two vectors are perpendicular then for L = (x, 0, z) the perpendicular (or normal line) to L in the plane LN will have the form (-z, 0, x) as these give a dot product of zero. Hence

``lineNormal ﻿= new BABYLON.Vector3(line.z, 0, -1 * line.x).normalize();``

The we need the unit vector in the direction of L

``line.normalize();﻿﻿``

Current ai tells us we are at wall w and bo is for wall w + 1. Since the walls are closed at the end wall w + 1 = 0. Hence the need to work modulo the number of walls

``(w + 1) % nbWalls``

Now we can use the right angled triangle to determine the position vector of bo. Starting from bi (corner of wall w + 1 mod nbWalls) travel along base and along height to get to bo (vector addition is commutative so can add in opposite order) as below

``Walls﻿] = walls[(w + 1) % nbWalls].corner.add(lineNormal.scale(ply)).add(line.scale(direction * ply/Math.tan(angle/2)));``

remember ply is distance between inner and outer wall so vector along height is scaled by ply. Knowing ply and the angle we can use tan to get the base length. Multiplying by direction deals with when angle is reflex or not.

we can then move on to the next line along

``line = nextLine.clone();﻿	``

and find the next line. Note we are using subtractToRef

V.subtractToRef(W, R) which takes W from V and puts the result into R

``walls[(w + 3) % nbWalls].corner.subtractToRef(walls[(w + 2) % nbWalls].corner, nextLine);	``

note that as ai is wall w, bi is wall w + 1 and ci is wall w + 2

Hope that helps

##### Share on other sites

One last thing;

What is the purpose of using indices array?

``````for(var w = 0; w <nbWalls; w++)
{
indices.push(w, (w + 1) % nbWalls, nbWalls + (w + 1) % nbWalls, w, nbWalls + (w + 1) % nbWalls, w + nbWalls); // base indices
}

currentLength = indices.length;
for(var i = 0; i <currentLength/3; i++)
{
indices.push(indices[3*i + 2] + 2*nbWalls, indices[3*i + 1] + 2*nbWalls, indices[3*i] + 2*nbWalls ); // top indices
}

for(var w = 0; w <nbWalls; w++)
{
indices.push(w, w + 2 *nbWalls, (w + 1) % nbWalls + 2*nbWalls, w, (w + 1) % nbWalls + 2*nbWalls, (w + 1) % nbWalls); // inner wall indices
indices.push((w + 1) % nbWalls + 3*nbWalls, w + 3 *nbWalls, w + nbWalls, (w + 1) % nbWalls + nbWalls, (w + 1) % nbWalls + 3*nbWalls, w + nbWalls); // outer wall indices
}
``````

And

Quote

To form the mesh, the base, top, inner wall and outer wall have to be split into triangular facets by grouping sets of three corners for each and pushing these into the indices array.

what does this mean?

Thanks

##### Share on other sites
On 11/9/2018 at 6:13 PM, JohnK said:

Current ai tells us we are at wall w and bo is for wall w + 1. Since the walls are closed at the end wall w + 1 = 0. Hence the need to work modulo the number of walls

```
`(w + 1) % nbWalls````

Now we can use the right angled triangle to determine the position vector of bo. Starting from bi (corner of wall w + 1 mod nbWalls) travel along base and along height to get to bo (vector addition is commutative so can add in opposite order) as below

```
`Walls﻿] = walls[(w + 1) % nbWalls].corner.add(lineNormal.scale(ply)).add(line.scale(direction * ply/Math.tan(angle/2)));````

remember ply is distance between inner and outer wall so vector along height is scaled by ply. Knowing ply and the angle we can use tan to get the base length. Multiplying by direction deals with when angle is reflex or not.

@JohnK Can you explain this bit more if you don't mind ?

##### Share on other sites

How much trigonometry and vectors do you know?

6 walls 0,1,2,3,4,5

x % 6 means x modulo 6 ie remainder when x is divded by 6

Walls join 0-1-2-3-4-5-0 get by adding 1 each time 5+1=6

Divide 6 by 6 remainder is 0 and  (5+1)%6=0

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account