Forge Autodesk model's transform matrix - javascript

I would like to know what are the two matrix below and what they are used for :
placementTransform (1 x 12)
refPointTransform (1 x 16)
Does anyone know what they are used ? I think it has to do with translation(Tx, Ty, Tz)/rotation (Rx, Ry, Rz) of 3D objects but there are too many parameters in each vector...

The placementTransform sets the position-offset and scale of a model during loading. refPointTransform is similar (but contains rotation), but is applied (multiplied) after the placementTransform.
Here is an example and source code, of how to use 'placementTransform':
https://github.com/wallabyway/viewer-multimodel-search/blob/1c2e71397a78ab807644f96dfb34b8e578825987/docs/index.html#L61
Take a look at line 61. When I load in the second model, I set the offset and scale of the 3D-building, so that it's positioned above the 3D-hand-saw.

Related

Procedural terrain generation with blocks

I am using three.js to create procedurally generated terrain using Perlin Noise.
I am creating the terrain using a series of blocks, but their heights along their borders are not corresponding to one another as you can see below.
How should I approach matching the height maps across blocks?
I'm using Perlin Noise Algorithm for generating heights; the problem is that the height of each point is indipendent from the heights of the near points. I've other noise algorithm, but i have the same problem..
There's a really good video on infinite terrain here: https://www.youtube.com/watch?v=IKB1hWWedMk
It's in processing, but the same concept can be applied to whichever noise library you're using - I'm going to assume that you're using Perlin noise. In which case, you need to look at the values you're passing into this function and change them based on how big your blocks are.
For example, imagine a 3x3 grid of blocks. If your middle block is (x, y), and each block is 10x10 units in size, if you move 'north' (for lack of a better term), you'd need to be getting (x, y - 10) from your noise function.
The video explains it way better than I can, but hopefully this has helped. Without more knowledge of the function you're using I can't really give a more detailed answer.
This answer will explain how to solve it for a single axis, x. It is then trivial to do the same for the y (z in three.js) axis.
The first step is to ensure the perlin noise is using the same random seed for each block. This will ensure that blocks share the same perlin noise map and so can transition smoothly between them.
The second part is to have a mapping between your block units and what is passed into the perlin noise function. For example your block x may be going from -512 to 512 units, so you get a height value for each x vertex by passing in -0.5 to 0.5 for each x vertex into the noise function.
E.g.
vertextHeight = perlin(vertexX / 1024, vertextY / 1024)
Your second block will then be offset so its edge interfaces with the first block. E.g. its x position will be +1024 more than the first block, and so will go from 512 to 1536.
So in this sense, block0 will have an x offset of 0, and block1 will have an x offset of 1024. 1024 being the block width/size in three.js units.
Finally, you need to give the same offsets to the noise function, but scaled based on the mapping described above. In this example, 512 would become 0.5 and 1536 would become 1.5 which looks like this:
size = 1024;
vertextHeight = perlin((vertexX + offsetX) / size, (vertextY + offsetY) / size)`
Therefore, the x value given to the noise function at the edge between block0 and block 1 will be the same, and so will return the same height value.

Understanding Matrix in SVG

I need help in deep understanding of matrix in SVG. I already know about matrix, I want to rotate and scale without using scale or rotate word. I want to use transform='matrix(a,b,c,d,e,f)'. I know 'a/d' value determine the scale, 'e/f' determines the position. tan(b),tan(c) determines the skew. cos(a),sin(b),-sin(c),cos(d) determines the angle.But I want to know how this work, I need thoroughly help in understanding matrix in SVG.
Matrix operations are composed of individual, "local" transformations (i.e. translate, rotate, scale, skew) by matrix concatenation (i.e. multiplication).
For example, if you want to rotate an object by r degrees around a point (x, y), you would translate to (x, y), rotate r degrees, then translate back to the original position (-x, -y).
By what is often referred to as "chaining" (as described above) each successive "local" transformation is combined to produce a result. Therefore, at any location in a chain of transformations, the "local" transformation space (at that location) is composed of all operations that came before.
What this implies is that when transforming some parameter of an SVG element (i.e. translate) the transform is applied to it's current transformation space. So, for example if the element is already rotated 30 degrees, then a translation of (8, 5) would not go 8 to the right and 5 down, but it would go the rotation of (8, 5) by 30 degrees - relative to the current position.
So this is a bit of a gotcha.
One way to help deal with this complication is to decompose transformation matrices into their individual, total transformations (i.e. total translation, total rotation/skew, total scale), but decomposition says nothing about what individual basic transformations went into the combined totals, nor of the order in which they occurred. This is a problem because 2D transformations are not commutative, e.g. translate(x, y)->rotate(r) is not the same as rotate(r)->translate(x, y).
The best way that I've found is to only compose transformations in a certain order and keep track of the totals in that order, then when a new transformation is introduced, used the totals that have been tracked, update the one that is being modified and recompose the entire transformation.
Like so: (pseudo-code)
// EDIT: initialize components (new SVGMatrix returns the identity matrix)
var transX=0, transY=0, rot=0, scaX=0, scaY=0, skwX=0, skwY=0, matrix = new SVGmatrix();
// example rotate
function rotate(svgEl, angle){
rot = rot + angle;
updateTransform();
applyTransform(svgEl);
};
function updateTransform(){
// the order that I've found most convenient
// (others may do it differently)
matrix.translate(transX, transY);
matrix.rotate(rot);
matrix.scale(scaX, scaY);
matrix.skewX(skwX);
matrix.skewY(skwY);
};
function applyTransform(el){
el.transform = matrix;
};
To be clear, this is not suggesting that matrices are not a good way of representing transformations, nor is it suggesting a better way - far from it.
Transformation matrices are a powerful tool, and when used appropriately, they are very effective at handling complex animations, but they are not trivial to use in all cases.
This may be a bit advanced, but for more information about animations using matrix transformations, this short code example provides a wealth of information and references to start from.
http://www.w3.org/TR/2011/WD-css3-2d-transforms-20111215/#matrix-decomposition
Update:
Just a note about the decomposed skew factor proposed at the above link.
Only a single skew factor ( in x ) is computed because skewing in both x and y is equivalent to a skew in x and a combined ( offset ) rotation.
Combining x skew and y skew ( with or without a rotation or translation, as in my above preferred composition order ) will result in a different x skew, rotation ( e.g. non-zero rotation if none was originally composed ), and translation ( e.g. an offset by some amount relative to the decomposed rotation in lieu of the original y skew ), but no recoverable y skew - using the linked decomposition method.
This is a limitation of composed affine matrices. So producing a final result matrix should generally be considered a one-way computation.

Distance between clusters in d3 multi foci force layout

I'm trying to understand this example of a multi-foci force layout...
http://bl.ocks.org/mbostock/1804919
It contains a "padding" variable (which defines the distance between nodes in each cluster), but I'm really struggling to see where the definition of the distances between clusters comes from - a combination of gravity and charge maybe?!
For example, if you wanted to double the distance between the clusters how could you achieve that? I've played with the customisable values in the example to no avail so would really appreciate any help from anyone. Thanks!
Setting m to a smaller value will increase the distance between clusters. This is the domain for the orginal scale x which is used to initialise the cx values on the elements of the nodes array.
Calling them cx and cy is a little bit confusing because they are not the cx and cy attributes of the circles.
The cx value for each node is is determined by feeding a random integer into the ordinal scale x By the statement cx: x(i).
The circles are moved toward the focii by calling gravity every tick (animation frame). This is done in the following statement...
d.x += (d.cx - d.x)*alpha
alpha is fixed at 0.5 in the tick function when calling gravity, but there is another alpha which could also be used. It's a variable maintained by the force object which is initially set to 0.1 before the first tick, and reduced by 1% every tick. It's passed to the tick function as e.alpha, so you could also try passing this value into the gravity function instead of a constant 0.5. The effect will be to cause the nodes to "cool down" more and more gradually until they stop.

Relation between LinkDistance and LinkStrength in D3.js Force layout

How are the LinkDistance and LinkStrength related in a force directed layout in D3.js? I am assuming that they are, correct me if i am wrong.
I understand that the linkDistance defines the length between any pair of nodes and essentially serves as constraint in a force layout. But what role does linkStrength play? The API documentation for D3.js defines it as the "strength (rigidity) of links to the specified value in the range [0,1]" What does "rigidity" mean here exactly?
You can see the link distance as the expected distance and the strength as the speed at which you want to reach this target distance on each iteration.
If you have a look at the source code of the force directed layout, you will find the following line:
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
This algorithm is an optimization algorithm, thus, on each iteration you modify l. Now the thing is that you have to specify by how much you modify this.
On a basic algorithm you would have the following in order to optimize the distances:
l = ((l = Math.sqrt(l)) - distances[i]) / l;
However you might want to have more control on every links and also on each individual link. Hence, you can consider the alpha attribute as the fixed parameter and the strength attribute as the parameter that varies for each link.
If you want to know more about the optimization method used, I recommend you to have a look at the Gauss-Seidel wikipedia page.

combine rotation and translation with three.js

i'm using Three.js (without shaders, only with existing objects methods) in order to realize animations, but my question is very simple : i'm sure it's possible, but can you tell me (or help me) how should i combine several animations on a shape ? For example, rotating and translating a sphere.
When i'm doing :
three.sphere.rotation.y += 0.1;
three.sphere.translateZ += 1;
the sphere rotates but the translation vector is also rotating, so the translation has no effect.
I know a bit openGL and i already have used glPushMatrix and glPopMatrix functions, so do them exist in this framework ?
Cheers
Each three.js object3D has a position, rotation and scale; the rotation (always relative to its origin or "center") defines its own local axis coordinates (say, what the object sees as its own "front,up, right" directions) and when you call translateZ, the object is moved according to those local directions (not along the world -or parent- Z axis). If you want the later, do three.sphere.position.z += 1 instead.
The order of transformation is important. You get a different result if you translate first and then rotate than if you rotate first and then translate. Of course with a sphere it will be hard to see the rotation.

Categories