How to store structured square grid data suitable for paraview? - paraview

I have some data like this
i j Rho ux vy
1 1 1.0 0 1.5
2 1 1.0 0.1 1
...
These numbers are center of cells coordinates (i and j) and other property values of that cell.
all cells are in the same size and are square.
how can I save my data so it can be read by Paraview?
Thank you for your attention.

I think that you could develop a ParaView writer converting your data into a VTK compatible format. Regarding the kind of cells you have, I suggest the .vti format specialized for vtkImageData for example.
The first step would be to transform the coordinates of center of cells into coordinates of points. Assuming s is the size of the cell and (i,j) the coordinates of its center :
// using d for visiblity
d = s/2
// the embedding is in the plane, the value of z is arbitrary
z = 0
// list of points for one cell
p0 = (i-d, j-d, z)
p1 = (i-d, j+d, z)
p2 = (i+d, j-d, z)
p3 = (i+d, j+d, z)
I used pseudo-code as you did not specify a language in particular. With this transformation, keep in mind that you should avoid duplicated points as connected cells shared common points.
Then the second step is to add the property values as scalar or vector fields (see vtkDataArray) associated on the cells (see vtkCellData).

A solution would be the following
Read you dataset as a table assuming it is a csv file.
Add a TableToPoints filter and set the I and J correctly.
Add a ResampleWithImageData filter to generate cells around the points.

Related

How to convert Matrix4x4 imported from .X to Unity? [duplicate]

I would like to change a 4x4 matrix from a right handed system where:
x is left and right, y is front and back and z is up and down
to a left-handed system where:
x is left and right, z is front and back and y is up and down.
For a vector it's easy, just swap the y and z values, but how do you do it for a matrix?
Let me try to explain it a little better.
I need to export a model from Blender, in which the z axis faces up, into OpenGL, where the y axis faces up.
For every coordinate (x, y, z) it's simple; just swap the y and z values: (x, z, y).
Because I have swapped the all the y and z values, any matrix that I use also needs to be flipped so that it has the same effect.
After a lot of searching I've eventually found a solution at gamedev:
If your matrix looks like this:
{ rx, ry, rz, 0 }
{ ux, uy, uz, 0 }
{ lx, ly, lz, 0 }
{ px, py, pz, 1 }
To change it from left to right or right to left, flip it like this:
{ rx, rz, ry, 0 }
{ lx, lz, ly, 0 }
{ ux, uz, uy, 0 }
{ px, pz, py, 1 }
I think I understand your problem because I am currently facing a similar one.
You start with a world matrix which transforms a vector in a space where Z is up (e.g. a world matrix).
Now you have a space where Y is up and you want to know what to do with your old matrix.
Try this:
There is a given world matrix
Matrix world = ... //space where Z is up
This Matrix changes the Y and Z components of a Vector
Matrix mToggle_YZ = new Matrix(
{1, 0, 0, 0}
{0, 0, 1, 0}
{0, 1, 0, 0}
{0, 0, 0, 1})
You are searching for this:
//same world transformation in a space where Y is up
Matrix world2 = mToggle_YZ * world * mToggle_YZ;
The result is the same matrix cmann posted below. But I think this is more understandable as it combines the following calculation:
1) Switch Y and Z
2) Do the old transformation
3) Switch back Z and Y
It is often the case that you want to change a matrix from one set of forward/right/up conventions to another set of forward/right/up conventions. For example, ROS uses z-up, and Unreal uses y-up. The process works whether or not you need to do a handedness-flip.
Note that the phrase "switch from right-handed to left-handed" is ambiguous. There are many left-handed forward/right/up conventions. For example: forward=z, right=x, up=y; and forward=x, right=y, up=z. You should really think of it as "how do I convert ROS' notion of forward/right/up to Unreal's notion of forward/right/up".
So, it's a straightforward job to create a matrix that converts between conventions. Let's assume we've done that and we now have
mat4x4 unrealFromRos = /* construct this by hand */;
mat4x4 rosFromUnreal = unrealFromRos.inverse();
Let's say the OP has a matrix that comes from ROS, and she wants to use it in Unreal. Her original matrix takes a ROS-style vector, does some stuff to it, and emits a ROS-style vector. She needs a matrix that takes an Unreal-style vector, does the same stuff, and emits an Unreal-style vector. That looks like this:
mat4x4 turnLeft10Degrees_ROS = ...;
mat4x4 turnLeft10Degrees_Unreal = unrealFromRos * turnLeft10Degrees_ROS * rosFromUnreal;
It should be pretty clear why this works. You take a Unreal vector, convert it to ROS-style, and now you can use the ROS-style matrix on it. That gives you a ROS vector, which you convert back to Unreal style.
Gerrit's answer is not quite fully general, because in the general case, rosFromUnreal != unrealFromRos. It's true if you're just inverting a single axis, but not true if you're doing something like converting X→Y, Y→Z, Z→X. I've found that it's less error-prone to always use a matrix and its inverse to do these convention switches, rather than to try to write special functions that flip just the right members.
This kind of matrix operation M * X * inverse(M) comes up a lot. You can think of it as a "change of basis" operation; to learn more about it, see https://en.wikipedia.org/wiki/Matrix_similarity.
I have been working on converting the Unity SteamVR_Utils.RigidTransform to ROS geometry_msgs/Pose and needed to convert Unity left handed coordinate system to the ROS right handed coordinate system.
This was the code I ended up writing to convert coordinate systems.
var device = SteamVR_Controller.Input(index);
// Modify the unity controller to be in the same coordinate system as ROS.
Vector3 ros_position = new Vector3(
device.transform.pos.z,
-1 * device.transform.pos.x,
device.transform.pos.y);
Quaternion ros_orientation = new Quaternion(
-1 * device.transform.rot.z,
device.transform.rot.x,
-1 * device.transform.rot.y,
device.transform.rot.w);
Originally I tried using the matrix example from #bleater, but I couldn't seem to get it to work. Would love to know if I made a mistake somewhere.
HmdMatrix44_t m = device.transform.ToHmdMatrix44();
HmdMatrix44_t m2 = new HmdMatrix44_t();
m2.m = new float[16];
// left -> right
m2.m[0] = m.m[0]; m2.m[1] = m.m[2]; m2.m[2] = m.m[1]; m2.m[3] = m.m[3];
m2.m[4] = m.m[8]; m2.m[5] = m.m[10]; m2.m[6] = m.m[9]; m2.m[7] = m.m[7];
m2.m[8] = m.m[4]; m2.m[9] = m.m[6]; m2.m[10] = m.m[5]; m2.m[11] = m.m[11];
m2.m[12] = m.m[12]; m2.m[13] = m.m[14]; m2.m[14] = m.m[13]; m2.m[15] = m.m[15];
SteamVR_Utils.RigidTransform rt = new SteamVR_Utils.RigidTransform(m2);
Vector3 ros_position = new Vector3(
rt.pos.x,
rt.pos.y,
rt.pos.z);
Quaternion ros_orientation = new Quaternion(
rt.rot.x,
rt.rot.y,
rt.rot.z,
rt.rot.w);
After 12 years, the question is still misleading because of the lack of description of axis direction.
What question asked for should probably be how to convert to .
The answer by #cmann is correct for the above question and #Gerrit explains the reason. And I will explain how to graphically get that conversion on the transform matrix.
We should be clear that orthogonal matrix contains both rotation matrix and point reflection(only point reflection will change the coordinate system between left-handed and right-handed). Thus they can be expressed as a 4x4 matrix and obey to transform matrix multiplying order. "The matrix of a composite transformation is obtained by multiplying the matrices of individual transformations."
to contains both rotation matrix and point reflection. But we can get the composite transformation graphically.
According to above image, after transformation, in RhC(Right-handedCorrdinate) will be in LfC as below
where is a transform bring points expressed in above RhC to points expressed in LhC.
Now We are able to convert () to () accroding to transform matrix multiplying order as below image.
The result is the same as #cmann's.
Result:
It depends if you transform your points by multiplying the matrix from the left or from the right.
If you multiply from the left (e.g: Ax = x', where A is a matrix and x' the transformed point), you just need to swap the second and third column.
If you multiply from the right (e.g: xA = x'), you need to swap the second and third row.
If your points are column vectors then you're in the first scenario.
Change sin factor to -sin for swaping coordinate spaces between right and left handed
Since this seems like a homework answer; i'll give you a start at a hint: What can you do to make the determinant of the matrix negative?
Further (better hint): Since you already know how to do that transformation with individual vectors, don't you think you'd be able to do it with the basis vectors that span the transformation the matrix represents? (Remember that a matrix can be viewed as a linear transormation performed on a tuple of unit vectors)

Apply operations to a cell array where each cell is a polygon

I have some problems that require me to manipulate polygons using operations such as translating, dilating, rotating, and shearing. The data I have is actually on state boundaries and geometries from data.gov on the state of Delaware. The function delaware.m returns a cell array (1x3 cell) of polygon matrices describing the shape of the state of Delaware, and this is the shape I need to do operations on. I will post the specific questions so you can get a sense of what I'm being asked of, but I'm still asking for more general guidance than a specific answer to each question.
Translate the state of Delaware so that its center is approximately at the origin.
Dilate the translated state of Delaware so that it fits inside a square of side length one centered at the origin.
Rotate the translated, dilated state of Delaware so that New Castle County is at the bottom and Sussex is at the top.
Dilate the translated, dilated, rotated state of Delaware without changing its area, so that it is about as wide as it is tall.
Shear the translated, dilated, rotated, dilated state of Delaware the northernmost tip is at least 2 units to the right of the southernmost tip.
The thing is, I know how to do all these operations in Matlab with just a single polygon/matrix. I am mostly struggling with how to use this with the cell array.
For example, say I have matrix S.
newS=S+[1;2]; %move S one unit to the right and two units up
R=[sqrt(2)/2 -sqrt(2)/2; sqrt(2)/2 sqrt(2)/2];
newS=R*S %rotate the polygon by 45 degrees
D = [alpha 0; 0 beta];
%alpha is the dilation scaling the x direction and beta in the y direction
%left multiply S by this dilation matrix to dilate along the cardinal axes
Sh=[1 y; 0 1] %y controls the amount of shearing
%left multiply by S to shear a shape along the x-axis relative to the y-axis
So for example, when I try to do an operation for moving the shape up/down/left/right as I described above for the cell array, I get the error message
Undefined operator '+' for input arguments of type 'cell'.
I also tried:
DEBoundary1 = cellfun(#sum, DEBoundary, [75.562;-39.6]);
%this is how much I wanted to move the polygons
But got:
>> Lab_code
Error using cellfun
All of the input arguments must be of the same size and shape.
Previous inputs had size 1 in dimension 1. Input #3 has size 2
I suppose in general, is there an easy way to take these operations I already know and apply them to a cell array consisting of polygon matrices? Or do I have to go about it a different way?
I believe this is what you're trying to do with your + example:
DEBoundary = {[0 1 -1 0; 1 -1 -1 1], [0 -1 1 0; 1 1 1 1]};
offset = [3;-2];
DEBoundary1 = cellfun(#(c) c + offset, DEBoundary, 'UniformOutput', false)
What this does is:
cellfun(#(c) % c is each element in the cell
c + offset % add the offset to each element
, DEB % The cell array to operate on
'UniformOutput', 0) % Specifies that the output is a cell and not a scalar
Try it online!
If you thing cellfun is confusing, then you may do this manually:
DEBoundary1 = cell(size(DEBoundary))
for i = 1:numel(DEBoundary)
DEBoundary1{i} = DEBoundary{i} + offset;
end
This should work with multiplication and other operations as well, as long as the dimensions match (but that's a mathematical question, not MATLAB specific).

Subtract vector from 3d array

Say if I have a 3d array:
lat = 45:49;
lon = -116:-110;
b = rand(5,7,12);
where the first dimension represents the latitude, the second dimension represents the longitude and the third row represents the data. I aim to plot this 3d data on a map using the mapping toolbox. But, before doing this, I would like to find the difference between the data in 'b' and the following vector:
vals = [2.3,5,6.8,5.4,3.3,12,1.5,4.6,9.8,82,3.3,1];
Specifically, for each spatial data point that I have in my mapped data I owuld like to calculate the mean absolute error between that vector and the data at each point in b. If these were two normal vectors I would use:
mae = mean(abs(bv - vals))
but I'm not sure how this can be done with the 3d array. Eventually, I aim to map this mean absolute error to see how it varies spatially. Can anyone suggest how this can be done in matlab?
Use bsxfun for this (it's more efficient than repmat):
V = permute(vals, [1,3,2]) %// Make sure that the dimesions 'align' correctly. i.e. 12 elements must go in the thrid dimension to match b
mae = mean(abs(bsxfun(#minus, b, V)),3)
As MATLAB does not support broadcasting, you need to create a matrix the same size as b with the repeated values of vals. To be able to do that, first you need to change vals to a shape of 1x1x12 and then repeat it 5x7 times. You can do that with
values=repmat(permute(vals,[1 3 2]),[5 7 1]);
now you can
mae = mean(abs(bv - values))

How to plot a 3D object from line segments in Matlab

I have a problem with fast plotting of a simple 3D model which I read from a .dxf file. The hole object is defined by points and the lines between them.
I have a matrix with coordinates. Every row is a unique point and every column is one coordinate.
Then I have an index matrix of size Nx2, where N is the number of rows in the model and on every row there are 2 points indexed from the coordinate matrix which should be connected by a line.
So the structure of the data is very similar to that of the data after triangulation and I need a function similar to trimesh or trisurf, though not for triangles, but for lines.
I can do that by letting a for loop cycle through the index matrix and plot every row separately, but it is very slow as compared built-in functions like trimesh.
Brief example:
%Coordinate matrix
NODES=[
-12.76747 -13.63075 -6.41142
-12.76747 -8.63075 -6.41142
-8.76747 -13.63075 -6.41142
-16.76747 -13.63075 -6.41142
-11.76747 -7.63075 -2.41142
];
%index matrix
LINES=[
1 2
3 4
1 4
3 5
1 5
];
%The slow way of creating the figure
figure(1)
hold on
for k=1:length(LINES)
plot3(NODES(LINES(k,:), 1), NODES(LINES(k,:), 2), NODES(LINES(k,:), 3), '.-')
end
view(20, 20)
hold off
I want to find a better and faster way to produce this figure
I think the code is self-explanatory (it assumes that NODES and LINES are already defined):
%'Calculated: edge coordinates and line specs'
TI = transpose(LINES);
DI = 2*ones(1,size(TI,2));
X = mat2cell(NODES(TI,1), DI);
Y = mat2cell(NODES(TI,2), DI);
Z = mat2cell(NODES(TI,3), DI);
L = repmat({'.-'}, size(X));
%'Output: plot'
ARGS = transpose([X,Y,Z,L]);
plot3(ARGS{:});

Generate Color Plot

There is an object on an area with dimension M*M unit cells. The coverage rate C=1/M * Sum(i=1 to M J(i)) where J(i)=1 when the cell i is covered and 0 otherwise. This is a color scale map representing the visit of the cells vs the times of visiting by the object. So, the legend shows that there are cells which have been visited from 0 to 8 times in N number of iterations. Can anyone tell me how this color representation can be coded? What and how this can be generated?
Use image (or imagesc). You need a matrix of X values and Y values, and the corresponding matrix of Z values.
For example:
% generate some x,y
[x,y]=meshgrid(1:10,1:10);
% generate some z values: random numbers from 0 to 8
z = randi([0 8],size(x));
% plot
imagesc(x,y,z)
How you determine your x, y, z ... well, you'd have to provide more information.
You could use a two dimensional array and read the information in from a file.