Rotate 3D function in Blender - math

I have a 3d coordinates XYZ (10,10,0) and I need to rotate this coordinate 20degrees around the axis X.
Is there a funcion that I could do that in Blender Scripint, like:
rotate3D([10,10,0],20, "X")
the result of this rotation should be:
X = 10.0000, Y = 9.3969, Z = 3.4202
Thanks

Related

Plane point rotation to a specific plane

I have a system where one axis is moving from [0 -> 2PI]. This movement generates an angled plane. Axis movement.
This yellow plane will be my target plane. I know the normal vector of this yellow plane and its constant. For me to calculate XYZ position on the yellow plane based on the rotation value of the axis (tool). I've come to a "solution" to first calculate what is the XYZ coordinate for a simpler plane vertical plane [1 0 0] as normal vector as I know the sphere origin and also the radius then it is easy to calculate any XYZ position based on the axis angle.
But my probelm is that now that I have the XYZ position on the gray plane: how can get my XYZ position to the corresponding position on the yellow plane? From gray plane to yellow plane Any suggestions would be appreciated.
Solution to this was simple.. I made it more complicated than necessary. There wasn't any need for transforming the points from one plane to another as these values could be calculated easily from the sphere origin and the plane orientation values.
// calculate axis rotation to radians
let radAngle = (angle)*Math.PI/180;
let beeta = (90*Math.PI/180) - radAngle; //rotation value on the circle
let gamma = Math.acos(yellow.normal.x); //plane orientation
// temporary vars
let cb = Math.cos(beeta);
let sb = Math.sin(beeta);
let cg = Math.cos(gamma);
let sg = Math.sin(gamma);
let x = sphere.origin.x + sphere.radius*(cg*sb);
let y = sphere.origin.y + sphere.radius*(sg*sb);
let z = sphere.origin.z + sphere.radius*cb;
Rotation sample

Converting 3D rotation to 2D rotation

I've been trying to figure out the 2D rotation value as seen from orthographic "top" view for a 3D object with XYZ rotation values in Maya. Maybe another way to ask this could be: I want to figure out the 2D rotation of a 3D obj's direction.
Here is a simple image to illustrate my question:
I've tried methods like getting the twist value of an object using quaternion (script pasted below), to this post I've found: Component of a quaternion rotation around an axis.
If I set the quaternion's X and Z values to zero, this method works half way. I can get the correct 2D rotation even when obj is rotated in both X and Y axis, but when rotated in all 3 axis, the result is wrong.
I am pretty new to all the quaternion and vector calculations, so I've been having difficulty trying to wrap my head around it.
;)
def quaternionTwist(q, axisVec):
axisVec.normalize()
# Get the plane the axisVec is a normal of
orthonormal1, orthonormal2 = findOrthonormals(axisVec)
transformed = rotateByQuaternion(orthonormal1, q)
# Project transformed vector onto plane
flattened = transformed - ((transformed * axisVec) * axisVec)
flattened.normalize()
# Get angle between original vector and projected transform to get angle around normal
angle = math.acos(orthonormal1 * flattened)
return math.degrees(angle)
q = getMQuaternion(obj)
# Zero out X and Y since we are only interested in Y axis.
q.x = 0
q.z = 0
up = om2.MVector.kYaxisVector
angle = quaternionTwist(q, up)
Can you get the (x,y,z) coordinates of the rotated vector? Once you have them use the (x,y) values to find the angle with atan2(y,x).
I'm not familiar with the framework you're using, but if it does what it seems, I think you're almost there. Just don't zero out the X and Z components of the quaternion before calling quaternionTwist().
The quaternions q1 = (x,y,z,w) and q2 = (0, y, 0, w) don't represent the same rotation about the y-axis, especially since q2 written this way becomes unnormalized, so what you're really comparing is (x,y,z,w) with (0, y/|q2|, 0, w/|q2|) where |q2| = sqrt(y^2 + w^2).
Here is a working code for Maya using John Alexiou's answer:
matrix = dagPath.inclusiveMatrix() #OpenMaya dagPath for an object
axis = om2.MVector.kZaxisVector
v = (axis * matrix).normal()
angle = math.atan2(v.x, v.z) #2D angle on XZ plane

how to use the rayshader packge for 3D surface from x, y, z

imagine I have a 3 columns matrix
x, y, z where z is a height/intensity of x and y.
x = runif(1000)
y = runif(1000)
z = rnorm(1000)
How to use the rayshader packge for 3D surface from x, y, z?
although the rgl could do it, i think is it possible to directly use the rayshader for 3D surface from x, y, z?
Thanks
hees
You could use akima::interp to approximate the surface with a matrix of values, and maybe rayshader::ray_shade can handle that. Code would be
m <- akima::interp(x, y, z, nx = 200, ny = 200)
s <- rayshader::ray_shade(m$z)
This gives a matrix of shade values; it doesn't draw anything. To draw something, you'll need to turn those values into colours, and display them. For example,
plot(as.raster(s))
which gives this plot:

Dimensions issue in 3D plotting

I have wrote the following code in scilab and want to plot it but the plot is not look like 3D. Basically the problem is dimensions, x and y are 1 cross 5 matrices and the function f is 5 cross 5 matrix. I tried to make x and y 5 dimensional by using meshgrid but then the functions can't give me result with that modified values of meshgrid(x,y). The whole code is here.
clear; clc;
//Defining the range of Cartesian coordinates (x,y,z)
x = linspace(1,30,5);
y = linspace(0,30,5);
z = linspace(0,30,5);
//------------------------------------------------------------------------------
//This funciton transform Cartesian to Spherical coordinates
function [r, theta, phi]=cart2sph(x, y, z)
r = sqrt(x^2+y^2+z^2);
theta = atan(y./x)
phi = acos(z./sqrt(x^2+y^2+z^2))'
endfunction
//------------------------------------------------------------------------------
//To get the spherical coordinates from Cartesian uing the above funciton
[r, theta, phi]=cart2sph(x, y, z)
//------------------------------------------------------------------------------
//Defining spherical hormonic as a funciton of shperical coordinates here.
function [y]=Y(l, m, theta, phi)
if m >= 0 then
y = (-1)^m/(sqrt(2*%pi))*exp(%i*m*phi)*legendre(l, m, cos(theta), "norm")
else
y = 1/(sqrt(2*%pi))*exp(%i*m*phi)*legendre(l, -m, cos(theta), "norm")
end
endfunction
l = 1; m = -1;
f = Y(l,m,theta,phi);
//I got the funciton value in spherical coordinates and
//that spherical coordinates are funciton of Cartesian coordinates.
//So basically funciton Y is a funciton of Cartesian coordinates (x,y,z).
//Next to plot funciton Y against (x,y)
//------------------------------------------------------------------------------
clf();
plot3d(x,y,f,flag=[2 4 4]); xtitle("|Y31(x,y)|");
Your problem is due to the range of f which is very small compared to the x and y ones.
To get what you expect you can proceed as follow
plot3d(x,y,f,flag=[2 4 4]); xtitle("|Y31(x,y)|");
ax=gca();
ax.cube_scaling="on";

3D Vector defined by 2 angles

So basically I'm looking for a way to calculate the x, y and z component of a vector using 2 angles as shown:
Where alpha is the 2D angle and beta is the y angle.
What I've been using uptill now for 2D vectors was:
x = Math.sin(alpha);
z = Math.cos(alpha);
After searching on stackexchange math I've found this forumula doesn't really work correctly:
x = Math.sin(alpha)*Math.cos(beta);
z = Math.sin(alpha)*Math.sin(beta);
y = Math.cos(beta);
Note: when approaching 90 degrees with the beta angle the x and z components should approach zero.
All help would be appreciated.
The proper formulas would be
x = Math.cos(alpha) * Math.cos(beta);
z = Math.sin(alpha) * Math.cos(beta);
y = Math.sin(beta);
That formula just come from the transformation of Spherical coordinates (r, theta, phi) -> (x, y, z) to Cartesian coordinates.

Resources