I want to get Screen Position from World Position in DirectX.
I can get my ball's world position. But I can't know how can I convert it to screen position.
You have a view/eye transform V (the one that "places" your "camera") and a projection transform P.
Clip space coordinates are reached by
clip_position = P * V * world_space_position
From clip space you reach NDC space by dividing the clip space coordinates by the 4th clip space coordinate w, i.e.
ndc_x = clip_x / clip_w
ndc_y = clip_y / clip_w
ndc_z = clip_z / clip_w
ndc_w = clip_w / clip_w = 1
The viewport XY coordinates are then reached by mapping the range [-1,1] to the viewport dimensions. The difference between OpenGL and DirectX is, that in OpenGL the depth range [-1,1] is mapped to [0, DEPTH_BUFFER_RESOLUTION], while in DirectX it's the depth range [0, 1] that maps to the depth buffer value range.
Related
I want to plot an NxN array of circles. Just to visualize, I attached an image of what I want to achieve. I'm new in MatlLab so I tried to plot a single circle first, and here is the sample code below:
n = 2^10; % size of mask
M = zeros(n);
I = 1:n;
x = I - n/2; % mask x - coordinates
y = n/2 - I; % mask y - coordinates
[X,Y] = meshgrid(x,y); % create 2-D mask grid
R = 200; % aperture radius
A = (X.^2 + Y.^2 <= R^2); % Circular aperture of radius R
M(A) = 1; % set mask elements inside aperture to 1
imagesc(M) % plot mask
axis image
I really don't have any idea on how to plot a 2D-array of circles. The distance between two circles is two radii. I need this for my research. Hoping anyone can help.A 4 x 4 array of circles.
If you just want to plot a set of circles, you can use the rectangle function within a loop
If in the call to rectangleyou set the Curvature property to 1 it will be drawn as circle (ref. to the documentation).
In the loop you hav to properly set the position of each rectangle (circle) by defining its lower left coordinates along with its width and height.
Having defined with n the number of circles and with d their diameter, you can compute the set of lower left coordinates as:
px=linspace(0,d*(nc-1),nc)
py=linspace(0,d*(nr-1),nr)
The black background can be either obtained by setting the color of the axes or by plotting another rectangle.
Then you can set the xlim and ylim to fit with the external rectangle.
You can also make the axex invisible, by setting its ○Visibleproperty tooff`.
Edit #1
Code updated to allow drawing a user-defined number of circles (set the number of rows and the number of columns)
% Define the number of circles
% Number of rows
nr=8
% NUmber of column
nc=8
% Define the diameter of the circle
d=6
% Create an axex and set hold to on
ax=axes
hold on
% Evalaute the lower left position of each circle
px=linspace(0,d*(nc-1),nc)
py=linspace(0,d*(nr-1),nr)
% Plot the background rectangle
rectangle('Position',[px(1),py(1),d*nc,d*nr],'Curvature',[0 0],'facecolor','k')
% Plot all the circles
for i=1:length(px)
for j=1:length(py)
rectangle('Position',[px(i) py(j) d d],'Curvature',1,'facecolor','w')
end
end
% Set the aspect ratio of the axes
daspect([1 1 1])
% Set the XLim and YLim
xlim([px(1) d*nc])
ylim([py(1) d*nr])
% Make the axes invisible
ax.Visible='off'
Edit #2
Aternative solution to address the OP comment:
If I want to make the axes fixed, say I want a meshgrid of 1024 by 1024, (the image size is independent of the circle radius) how do I incorporate it in the code?
If you want to use a fixed (1024 x 1024) mask on which to plot the circles, starting from the cde you've posted in the question, you can simply do the following:
define the number of circles you want to plot, on a (1024 x 1024) mask they can be 2, 4, 8, ...
define a basic mask holding just one circle
identify the points inside that circle and set them to 1
Replicate (using the function repmat the basic mask accoding to the numner of circles to be plotted
The implemntation, based on your code could be:
% Define the number of circles to be plotted
% on a (1024 x 1024) mask they can be 2, 4, 8, ...
n_circles=4
% Define the size of the basic mask
n0 = (2^10)/n_circles;
% Initialize the basic mask
M0 = zeros(n0);
% Define the x and y coordinates of the basic mask
I = 1:n0;
x = I - n0/2;
y = n0/2 - I;
% Create the mask
[X,Y] = meshgrid(x,y);
% Define the radius of the basic circle
R = n0/2;
% Get the indices of the points insiede the basic circle
A = (X.^2 + Y.^2 <= R^2);
% Set basic mask
M0(A) = 1;
% Open a FIgure
figure
% Replicate the basic mask accoding to the numner of circles to be plotted
M=repmat(M0,n_circles,n_circles);
% Display the mask
imagesc(M)
% Set the axes aspect ratio
daspect([1 1 1])
So the idea is quite simple: given the sun's position (azimuth and elevation) I want my app to be able to display a shape using augmented reality when the camera is pointing at the sun.
So there is a few steps:
Convert azimuth and elevation into radians, then into cartesian coordinates to get a simple vector {x, y, z}.
Get the phone's gyroscope data to get its orientation in space as a 3D vector {x, y, z}.
Calculate new coordinates for the sun regarding the phone orientation.
Display a random shape using Three.js at these coordinates.
1 and 2 are quite easy. There are a lot of APIs out there giving the sun's position depending on a location. Then I used a formula to convert the sun's spherical coordinates into cartesian ones:
x = R * cos(ϕ) * sin(θ)
y = R * cos(ϕ) * cos(θ)
z = R * sin(ϕ)
with R, the distance of the point from the origin, θ (the azimuth) and ϕ (the elevation).
I got the device's orientation in space with Expo.io, using their Device Motion API. Documentation here
I'm really struggling with the third step. I don't know how to combine sun and device coordinates in space, and project the whole thing through Three.js perspective camera.
I found this post the other day: Compare device 3D orientation with the sun position but I've found the explanations a bit confusing.
Let's say I want to display a cube with Three:
const geometry = new THREE.BoxGeometry(0.07, 0.07, 0.07);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.x = 0;
cube.position.y = 0;
cube.position.z = -1;
The final goal here will be to find the correct {x, y, z} so the cube can be displayed at the sun's location. This vector will be of course updated every time the user moves his phone in space.
I have two sets of Lat and Long values corresponding to two corners of a rectangle (top left and bottom right). I want to load a image in the rectangle and as the user clicks on the locations on the rectangle/image, it should return a latitude and longitude (from the detected pixel's coordinates). What should be the calculation to convert pixels to lat and long, given the above spot of inputs.
You should know what geodetic projection has been used to create that map and how rectangular coordinates correspond to geographic ones.
For small map pieces you can use linear approximation, so coordinates might be calculated with linear interpolation.
Example for x-coordinate and longitude:
Lon = LonLeft + X * (LonRight - LonLeft) / Width
Assuming linear interpolation is good enough for your purposes, you can use following formula:
out = (in - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
where in* are image coordinates and out* are map coordinates.
You have to use formula twice; once for horizontal and once for vertical coordinate.
I have an Nx3 array which stores the values in N coordinates. The first and second column correspond to x and y coordinate respectively, and the third column represents the value at that coordinates. I want to plot a 2D intensity plot, what's the best way to do it?
If the coordinates are evenly spaced, then I can use meshgrid and then use imshow, but in my data the coordinates are not evenly spaced. Besides, the array is very large N~100000, and the values (third column) span several orders of magnitude (so I should be using a logplot?). What's the best way to plot such a graph?
You can use griddata to interpolate your data at all 100000 points to a uniform grid (say 100 x 100) and then plot everything with a Log scaling of the colours,
x = data[:,0]
y = data[:,1]
z = data[:,2]
# define grid.
xi = np.linspace(np.min(x),np.max(x),100)
yi = np.linspace(np.min(y),np.max(y),100)
# grid the data.
zi = griddata(x,y,z,xi,yi,interp='linear')
#pcolormesh of interpolated uniform grid with log colormap
plt.pcolormesh(xi,yi,zi,norm=matplotlib.colors.LogNorm())
plt.colormap()
plt.show()
I've not tested this but basic idea should be correct. This has the advantage that you don't need to know your original (large) dataset and can work simply with the grid data xi, yi and zi.
The alternative is to colour a scatterplot,
plt.scatter(x, y, c=z,edgecolors='none', norm=matplotlib.colors.LogNorm())
and turn off the outer edges of the points so they make up a continuous picture.
With reference to this programming game I am currently building.
alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg
To translate a Canvas in WPF, I am using two Forms: TranslateTransform (to move it), and RotateTransform (to rotate it) [children of the same TransformationGroup]
I can easily get the top left x,y coordinates of a canvas when its not rotated (or rotated at 90deg, since it will be the same), but the problem I am facing is getting the top left (and the other 3 points) coordinates.
This is because when a RotateTransform is applied, the TranslateTransform's X and Y properties are not changed (and thus still indicate that the top-left of the square is like the dotted-square (from the image)
The Canvas is being rotated from its center, so that is its origin.
So how can I get the "new" x and y coordinates of the 4 points after a rotation?
[UPDATE]
alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg
I have found a way to find the top-left coordinates after a rotation (as you can see from the new image) by adding the OffsetX and OffsetY from the rotation to the starting X and Y coordinates.
But I'm now having trouble figuring out the rest of the coordinates (the other 3).
With this rotated shape, how can I figure out the x and y coordinates of the remaining 3 corners?
[EDIT]
The points in the 2nd image ARE NOT ACCURATE AND EXACT POINTS. I made the points up with estimates in my head.
[UPDATE] Solution:
First of all, I would like to thank Jason S for that lengthy and Very informative post in which he describes the mathematics behind the whole process; I certainly learned a lot by reading your post and trying out the values.
But I have now found a code snippet (thanks to EugeneZ's mention of TransformBounds) that does exactly what I want:
public Rect GetBounds(FrameworkElement of, FrameworkElement from)
{
// Might throw an exception if of and from are not in the same visual tree
GeneralTransform transform = of.TransformToVisual(from);
return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight));
}
Reference: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/
If I understand your question right:
given:
shape has corner (x1,y1), center (xc,yc)
rotated shape has corner (x1',y1') after being rotated about center
desired:
how to map any point of the shape (x,y) -> (x',y') by that same rotation
Here's the relevant equations:
(x'-xc) = Kc*(x-xc) - Ks*(y-yc)
(y'-yc) = Ks*(x-xc) + Kc*(y-yc)
where Kc=cos(theta) and Ks=sin(theta) and theta is the angle of counterclockwise rotation. (to verify: if theta=0 this leaves the coordinates unchanged, otherwise if xc=yc=0, it maps (1,0) to (cos(theta),sin(theta)) and (0,1) to (-sin(theta), cos(theta)) . Caveat: this is for coordinate systems where (x,y)=(1,1) is in the upper right quadrant. For yours where it's in the lower right quadrant, theta would be the angle of clockwise rotation rather than counterclockwise rotation.)
If you know the coordinates of your rectangle aligned with the x-y axes, xc would just be the average of the two x-coordinates and yc would just be the average of the two y-coordinates. (in your situation, it's xc=75,yc=85.)
If you know theta, you now have enough information to calculate the new coordinates.
If you don't know theta, you can solve for Kc, Ks. Here's the relevant calculations for your example:
(62-75) = Kc*(50-75) - Ks*(50-85)
(40-85) = Ks*(50-75) + Kc*(50-85)
-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks
which is a system of linear equations that can be solved (exercise for the reader: in MATLAB it's:
[-25 35;-35 -25]\[-13;-45]
to yield, in this case, Kc=1.027, Ks=0.3622 which does NOT make sense (K2 = Kc2 + Ks2 is supposed to equal 1 for a pure rotation; in this case it's K = 1.089) so it's not a pure rotation about the rectangle center, which is what your drawing indicates. Nor does it seem to be a pure rotation about the origin. To check, compare distances from the center of rotation before and after the rotation using the Pythagorean theorem, d2 = deltax2 + deltay2. (for rotation about xc=75,yc=85, distance before is 43.01, distance after is 46.84, the ratio is K=1.089; for rotation about the origin, distance before is 70.71, distance after is 73.78, ratio is 1.043. I could believe ratios of 1.01 or less would arise from coordinate rounding to integers, but this is clearly larger than a roundoff error)
So there's some missing information here. How did you get the numbers (62,40)?
That's the basic gist of the math behind rotations, however.
edit: aha, I didn't realize they were estimates. (pretty close to being realistic, though!)
I use this method:
Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));
where rotateTransform is the instance on which I work and set Angle...etc.
Look at GeneralTransform.TransformBounds() method.
I'm not sure, but is this what you're looking for - rotation of a point in Cartesian coordinate system:
link
You can use Transform.Transform() method on your Point with the same transformations to get a new point to which these transformations were applied.