getting equivalent pixel of two different wide resolutions - c++

I want to get the equivalent pixel location of two different wide resolutions.
Here is an example.
In a 1366x768 resolution, the desired pixel is located in row 120 and column 300.
I want to convert it to a lower resolution and get the equivalent of 120x300 point from the original to the converted one.

Use percent.
e.g. 120/1366=60/683=x ~ 0.0878 and 300/768=25/64=y ~ 0.3906. Now simply multiply these percent with your desired resolution.
For example if you have the resolution 800x600 and want this position just multiply.
x = 800 * 0.0878 = 70.24
y = 600 * 0.3906 = 234.36
This works because the position got kindof 'normalized' so that it lays between 0 and 1. Whatever you multiply this with will have same 'dimensions'. e.g. assume we want the position 400x300 from screen 800x600 in another screen so that it has same ratios. We can do similiar to your problem up there:
x = 400 / 800 = 0.5
y = 300 / 600 = 0.5
To get the position for any other screen we multiply the result from there with the resolution.
Percentage

Related

Rotating matrix by N degrees

I have a matrix A[M][M] and I want to rotate it N degrees relative to the center of the matrix, discarding the values which its new position is outside the original matrix and filling the missing values with zeroes. I am using the following formula to get he new positions:
newXPosition = ceil(cos(N*PI/180)*(oldXPosition - M/2) - sin(N*PI/180)*(oldYPosition - M/2) + M/2)
newYPosition = ceil(sin(N*PI/180)*(oldXPosition - M/2) + cos(N*PI/180)*(oldYPosition - M/2) + M/2)
However, this is failing at some point. If we look for newXPosition and newYPosition for oldXPosition = oldYPosition = 0, M = 32 and N = 90ยบ, We get newXPosition = 32, newYPosition = 0. Taking into account that the dimensions are [0-31], it will not work to just substract one to newXPosition because in other occasions it would be newYPosition the variable that will have to be substracted, or even both.
Does anyone know where am I failing?
PS: I have already read a couple of answers regarding the 90 degrees rotation, but my intention is not to rotate the matrix 90 degrees, but N.
If you think as each pixel as a small square you see that their center is at 0.5, 1.5 etc; so add "0.5" to oldXPosition - and subtract it when forming newXPosition:
newXPosition = ceil(cos(NPI/180)(oldXPosition+0.5- M/2) - sin(NPI/180)(oldYPosition+0.5- M/2)+M/2-0.5)
So, in your case newXPosition would be 31 - not 32, and newYPosition 0.
I would also recommend you to reverse the logic, so instead of figuring out the new positions based on old x and y, you start with the new matrix and for each pixel you find out the old position that corresponded to (which is like rotating -N degrees with your formulas) - and take the value from that one.
Otherwise a "solid" shape might get zeros due to the rotation.
Instead of "ceil" you might do some fancy interpolation.

How to find an Equivalent point in a Scaled down image?

I would like to calculate the corner points or contours of the star in this in a Larger image. For that I'm scaling down the size to a smaller one & I'm able to get this points clearly. Now How to map this point in original image? I'm using opencv c++.
Consider a trivial example: the image size is reduced exactly by half.
So, the cartesian coordinate (x, y) in the original image becomes coordinate (x/2, y/2) in the reduced image, and coordinate (x', y') in the reduced image corresponds to coordinate (x*2, y*2) in the original image.
Of course, fractional coordinates get typically rounded off, in a reduced scale image, so the exact mapping is only possible for even-numbered coordinates in this example's original image.
Generalizing this, if the image's width is scaled by a factor of w horizontally and h vertically, coordinate (x, y) becomes coordinate(x*w, y*h), rounded off. In the example I gave, both w and h are 1/2, or .5
You should be able to figure out the values of w and h yourself, and be able to map the coordinates trivially. Of course, due to rounding off, you will not be able to compute the exact coordinates in the original image.
I realize this is an old question. I just wanted to add to Sam's answer above, to deal with "rounding off", in case other readers are wondering the same thing I faced.
This rounding off becomes obvious for even # of pixels across a coordinate axis. For instance, along a 1-D axis, a point demarcating the 2nd quartile gets mapped to an inaccurate value:
axis_prev = [0, 1, 2, 3]
axis_new = [0, 1, 2, 3, 4, 5, 6, 7]
w_prev = len(axis_prev) # This is an axis of length 4
w_new = len(axis_new) # This is an axis of length 8
x_prev = 2
x_new = x_prev * w_new / w_prev
print(x_new)
>>> 4
### x_new should be 5
In Python, one strategy would be to linearly interpolate values from one axis resolution to another axis resolution. Say for the above, we wish to map a point from the smaller image to its corresponding point of the star in the larger image:
import numpy as np
from scipy.interpolate import interp1d
x_old = np.linspace(0, 640, 641)
x_new = np.linspace(0, 768, 769)
f = interp1d(x_old, x_new)
x = 35
x_prime = f(x)

Get size of excel cell in pixels

I am trying to programatically (C++ but VBA explanations are OK) get the size of an excel cell in pixels. The excel application gui shows the size of the cell as:
Width: 8.28 (160 pixels) Height: 24.6 (41 pixels), Font is Arial 20 pt.
Using an excel range I can get the:
ColumnWidth: 8.3, RowHeight: 24.6
Range Width: 96, Range Height 24.6
I tried using PointsToScreenPixelsX and PointsToScreenPixelsY for all of the above values but they returned values which didn't match up with what the excel gui said (396 for row/cell height, 136 for column width and 224 for column width).
Any ideas?
The conversion from points to pixels depends on your DPI setting. There are 72 points to an inch, so if you have 96 points that's 4/3 of an inch. If your DPI (in Display Properties) is 120 then that works out to 160 pixels.
In other words, pixels = points * DPI / 72.
However, this doesn't take zoom into account. ActiveWindow.Zoom in Excel is a percentage, so for instance 200 is twice normal size. Note that the UI still shows unzoomed pixels.
The OP stated:
The excel application gui shows the size of the cell as:
Width: 8.28 (160 pixels) Height: 24.6 (41 pixels), Font is Arial 20 pt.
First let me clarify: the application gui shows column widths and height in a decimal measurement and a pixel measurement, regardless of font size, screen size, zoom, etc. For any of these factors, if the Excel column width is 8.43, it will always be defined as 64 pixels. Second, I am a little confused, because my version of Excel (2010 currently) and every prior version I can remember had the standard column width of 8.43 equal 64 pixels; likewise, the standard row height of 15 equals 20 pixels, which does not seem to match the OP's example.
Having established that, one poster asked "Why?" One reason: if you're adjusting column widths or row heights, Excel allows that in discrete units that, unfortunately, they decided to name pixels. Maybe they related to pixels in some early version, but they seem just as random as the units used - 8.43 is what, inches, picas, ??? Not twips, that's for sure! Here, I'll call it a decimal unit.
Anyway, for all column widths over 1.00, that discrete pixel unit is 1/7th of a decimal unit. Bizarrely, column widths under 1.00 are divided into 12 units. Therefore, the discrete widths up to the 2.00 decimal unit are as follows:
0.08, 0.17, 0.25, 0.33, 0.42, 0.5, 0.58, 0.67, 0.75, 0.83, 0.92, 1.00,
1.14, 1.29, 1.43, 1.57, 1.71, 1.86, 2.00
with 2.00 equaling 19 pixels. Yes, I'll pause while you shake your head in disbelief, but that's how they made it.
Fortunately, row heights appear to be more uniform, with 1 pixel equaling 0.75 decimal units; 10 pixels equaling 7.50; standard row height of 20 pixels equaling 15.00; and so on. Just in case you should ever need to convert between these randomly discrete units, here are a couple of VBA functions to do so:
Function ColumnWidthToPixels(ByVal ColWidth As Single) As Integer
Select Case Round(ColWidth, 4) ' Adjust for floating point errors
Case Is < 0:
ColumnWidthToPixels = ColumnWidthToPixels(ActiveSheet.StandardWidth)
Case Is < 1:
ColumnWidthToPixels = Round(ColWidth * 12, 0)
Case Is <= 255:
ColumnWidthToPixels = Round(12 + ((Int(ColWidth) - 1) * 7) _
+ Round((ColWidth - Int(ColWidth)) * 7, 0), 0)
Case Else:
ColumnWidthToPixels = ColumnWidthToPixels(ActiveSheet.StandardWidth)
End Select
End Function
Function PixelsToColumnWidth(ByVal Pixels As Integer) As Single
Select Case Pixels
Case Is < 0:
PixelsToColumnWidth = ActiveSheet.StandardWidth
Case Is < 12:
PixelsToColumnWidth = Round(Pixels / 12, 2)
Case Is <= 1790:
PixelsToColumnWidth = Round(1 + ((Pixels - 12) / 7), 2)
Case Else:
PixelsToColumnWidth = ActiveSheet.StandardWidth
End Select
End Function
Example
This example determines the height and width (in pixels) of the selected cells in the active window and returns the values in the lWinWidth and lWinHeight variables.
With ActiveWindow
lWinWidth = PointsToScreenPixelsX(.Selection.Width)
lWinHeight = PointsToScreenPixelsY(.Selection.Height)
End With

OpenGL - GlVertex relative/absolute position

Imagen I have a list of 2D points (x,y) that describe a 2D terrain in my simple game.
I have then glVertex() to draw all those points in GL_POINTS mode.
Then I have a Ball that also has it's (x,y) coordinates.
I want the ball to have a definite size in relation to everything else (such as the terrain).
How should I set the values of the (x,y) coordinates to draw everything the size I want it?
Having a 600x400 screen.
I am troubled also because glVertex2f(1,1) will draw a primitive point on the upper right corner. So 1 represents to go 100% to the right or top. But the screen is 600x400 so I can't have dimensions of equal length on x and y axis.
Since 0 is 0% (absolute left/bottom) and 1 is 100% (absolute right/top), you just have to find a point in between that will line up with the pixels.
For example. Say your ball is 20x20 pixels. This means that it is 5% of the screen tall and 3.33% of the screen wide. Therefore, the square surrounding your ball would have the following vertices:
void drawBall()
{
glVertex2f(ball.x - (20/600)/2, ball.y - (20/400)/2);
glVertex2f(ball.x - (20/600)/2, ball.y + (20/400)/2);
glVertex2f(ball.x + (20/600)/2, ball.y + (20/400)/2);
glVertex2f(ball.x + (20/600)/2, ball.y - (20/400)/2);
}
See how I'm dividing the width of the ball by the width of the screen to get a floating point value that works with glVertex2f? Also, ball.x and ball.y should be a floating point value between 0 and 1.
I divide these numbers by 2 because I'm assuming that (ball.x, ball.y) is the coordinate of the center of the ball, so half of the addition goes on either side of the center.
You can write your own function that draws the vertices and that takes pixels in arguments:
#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 400
void glVertex_pixels(const double x,const double y){
glVertex2d(x * 2.0 / (double)WINDOW_WIDTH - 1.0, 1.0 - y * 2.0 / (double)WINDOW_HEIGHT);
}
You can also use a macro:
#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 400
#define glVertex_pixels(x,y) glVertex2d((double)(x) * 2.0 / (double)WINDOW_WIDTH - 1.0, 1.0 - (double)(y) * 2.0 / (double)WINDOW_HEIGHT);
No matter which of the above codes you use, the use of this function is simple. For example, the following code draws a vertex 10 pixels from the left side and 20 pixels from the top side:
glVertex_pixels(10,20);

how to Convert Lat ,long to an XY coordinate system (e.g. UTM) and then map this to pixel space of my Image

I have a very small area map , which I downloaded from Openstreet map(PNG) and also its OSM(.osm) file which contains its Lat ,long.
Now I want to convert Lat ,long to an XY coordinate system (e.g. UTM) and then map this to pixel space of my Image which is of size (600 x 800 ). I know its a two way process ,like to know how to do this . Thank you
GPS Coordinates to Pixels
Assuming this map does not cross prime meridian
Assuming pixel 0,0 is upper left, and pixel 600,800 is lower right.
Assuming map is Northern Hemisphere Only (no part of map is southern hemisphere)
Determine the left-most longitude in your 800x600 image (X)
Determine the east-most longitude in your 800x600 image (Y)
Determine Longitude-Diff (Z = Y - X)
Determine north-most latitude in your 800x600 image (A)
Determine south-most latitude in your 800x600 image (B)
Determine Longitude-Diff (C = A - B)
Given a Latitude and Longitude, to determine which pixel they clicked on:
J = Input Longitude
K = Input Latitude
Calculate X-pixel
XPixel = CInt(((Y - J) / CDbl(Z)) * 800)
Calculate Y-pixel
YPixel = CInt(((A - K) / CDbl(C)) * 600)
UTM
Here is a cartographic library that should help with GPS to UTM conversions