c# Image Coordinates Processing - c#

If we have 2 same images. One is small and one is big. Now we have x y value on small image
then how we will map it on the same position on big image. Can anyone tell me with formula?

I'd imagine you'd just scale it:
int bigX = smallX * (bigWidth / smallWidth);
int bigY = smallY * (bigHeight / smallHeight);
Note that you may wish to use floating point arithmetic to avoid integer arithmetic issues:
int bigX = (int) (smallX * ((double) bigWidth / smallWidth));
int bigY = (int) (smallY * ((double) bigHeight / smallHeight));

Simply use proportions.
Point bigpoint = new Point((int)(smallpoint.X * bigwidth/smallwidth),
(int)(smallpoint.Y * bigheight/smallheight));
// Assuming that Point smallpoint is the pixel of small image

Related

scaling 4:3 points to 16:9 points

I have an array of points which all range from x(0-512) and y(0-384) which means an aspect ratio of 4:3.
If I want to display every points, perfectly, on a 16:9 monitor, what math would be needed to achieve this?
Let's say "ee" is my 4:3 point and "point" is the 16:9 point I need..
I thought since I'm trying to scale it on a 1920:1080 monitor, which is a 16:9 aspect ratio
point = new PointF(ee.x * (1920 / 512), ee.y * (1080 / 384));
But this seems to be off by abit.
Any help? Thanks.
You can't match exactly the aspect other than by multiplying each dimension by an integer. Here the only integer that would fit is 2 (cause 384 * 3 > 1080)...
so you would have to do:
point = new Point (ee.x * 2, ee.y * 2);
and you could center it with:
point = new Point (ee.x * 2 + ((1920 - 512*2)/2), ee.y * 2 + ((1080 - 384*2)/2)));
Hope that helps...
Edit: with floats, you have to take the minimum of the multiplier:
var multiplier = Math.Min(1920.0/512, 1080.0/384);
point = new Point (ee.x * multiplier + ((1920 - 512*multiplier)/2), ee.y * multiplier + ((1080 - 384*multiplier)/2)));
Could you elaborate what you mean by "off"?
If you mean that the image looks stretched horizontally, it is because the aspect ratio is larger than before. If you want the image to look like what it was before (but bigger), you'll need to scale one axis by the aspect ratio to fix it.
aspect_ratio_before = 4.0f / 3.0f;
aspect_ratio_after = 16.0f / 9.0f;
// This is equal to 4/3.
aspect_ratio_difference = aspect_ratio_after / aspect_ratio_before;
// I squish the X axis here.
point.x /= aspect_ratio_difference;
// Alternatively, you can also multiply point.y by the
// aspect_ratio_difference, though that will stretch the Y axis instead.
// Use only one!
// point.y *= aspect_ratio_difference;
Disclaimer: I have not worked with .net before, so I don't know all the details of its rendering engine. This is based off my experience working with OpenGL and scaling.

How do I save intermediate fractional results when the input and output should be integer?

I'm trying to create a BMI calculator using c#.
My formula is BMI = (weight /(height * height)) * factor.
Example: BMI = (172 / (73 * 73 )) * 703
BMI = (172 / 5329) * 703
BMI = ( 0.032) * 703
BMI = 22.69
My problem is that after I divide the weight by the height I'm getting a fraction, despite the fact that when I multiply it by the factor it's above 1, I can't save it in my integer variable. So my total BMI is always coming out at 0.
Do I need to rethink my data types? or should I be converting them? I'm unsure how to resolve the issue.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Calculate_Click(object sender, EventArgs e)
{
int feet, inches, height, pounds, result, factor;
factor = 703;
//convert the text input to the correct data type
feet = Convert.ToInt32(feetBox.Text);
inches = Convert.ToInt32(inchesBox.Text);
pounds = Convert.ToInt32(poundsBox.Text);
//turn the feet and inches into a single height value in inches
height = (feet * 12) + inches;
//calculate the BMI
//result = (pounds / (height * height) ) * factor;
result = factor * (pounds / (height * height));
// output the results
output.Text = String.Format("Your BMI is: {0}", result);
}
}
You are facing integer division. If you divide integer by integer the result is again integer. To fix this problem you have to cast value to floating type (float/double). That will fix the problem.
double result = factor * (pounds / (double)(height * height));
This way you will force the result to be decimal number.
EDIT:
The problem is following. Imagine the integers as physical objects - apples for example.
7/3 you have 7 apples, and you want to give to 3 kids. How many apples will each kid get? The answer is 2. The remainder is 1 of course. But the integer division doesn't return the remainder, so this information is 'lost' in the process of division.
When programming, the rule of thumb is, to stick with integer as long as it is possible. Because of the way decimal number are stored in memory, there are some errors. Note that up to some arbitrary value integers can be stored in floating types without loss of precision, but starting at the threshold, there are errors even for integer numbers.
Try 123456789 in the float converter below, it won't be stored exactly, that's why is better to stick with integers as long, as you can.
Great tool to examine those imperfections is this float converter. For example 0.5 can be stored precisely but 0.6 cannot. Try it yourself.
You should never get a negative number from a division of 2 positive numbers. Therefore if you are getting a negative result one of your inputs is a negative number (and as you are multiplying height by itself the negative must be coming from the weight).
If you want the result to be an integer value then moving the factor multiplier inside the parenthesis would be ok:
int result = (factor * weight) / (height * height);
This would work because factor * weight will always be larger than height * height, and hence the answer will a none-zero integer.
If you want decimals in your result (which BMI usually contains e.g. 22.6) then you need to perform floating point division, rather than integer division. The easiest way to do this would be to change all of your variables to double, rather than int, or to simple introduce a decimal number into to the equation at the beginning. The following would produce the correct result:
double factor = 703.0;
double result = (factor * weight) / (height * height);
Yes, you need to change the data type of BMI (result) from int to double. I hope then everything will work.
Please replace existing line of code : int feet, inches, height, pounds, result, factor;
with
double feet, inches, factor, result, height, pounds, ;

Double precision problems when zooming in

I have this algorithm that calcuates the mandelbrot value of a point (x0,y0) (x0 and y0 are somewhere between -1 and 1 i thought, not very important). This is all going very well when scale isn't getting too big, but at higher values of scale, the values returned are very inaccurate and my graphic output starts to go freaky. How do i predict from what value of scale this occurs?
public static byte CalculateMandelbrot(double x0, double y0,double scale)
{
x0 /= scale;
y0 /= scale;
double y = 0;
double x = 0;
byte i = 0;
while (x * x + y * y < 4)
{
double tx = x;
x = x * x - y * y + x0;
y = 2 * tx * y + y0;
i++;
if (i == 0xFF) break;
}
return i;
}
A double has 53 bits of precision. This amounts to about 16 decimal places.
If you zoom in on your fractal 10^13 times, and make picture of 1000x1000 pixels, the precision is about the same as the screen resolution: the minimal change possible in a double is a step of one pixel on the screen.
But you will get into trouble before that, because you iterate the mandelbrot formula a hundred times iteratively on the same number. Each calculation adds a roundoff error (multiple ones, probably) of about 1/10^16. It is possible (although tedious) to predict when this gets noticable.
The FPU internally has a higher number of bits than standard double, this will reduce the abovementioned effect.
This is the classic "decimal vs double" pitfall.
Try using 'decimal' for all vars and see if it clicks.
From the C# Reference page:
Compared to floating-point types, the decimal type has a greater
precision and a smaller range
There are also arbitrary precision implementations like BigFloat Class.

Strange arithmetic error with vectors

I am using DirectX to draw on screen.
I want to make the image about whilst keeping the dimensions, so I am assigning some arithmetic to the vertexes:
float boxPosFactorX = (869-3)+(100/100 * (1063 - 869));
float boxPosFactorY = (940-3)+(100/100 * (1038 - 940));
vertexes[0].Position = new Vector4((50 * boxScale) + boxPosFactorX, (50 * boxScale) + boxPosFactorY, 0, 1.0f);
// other vertexes with same structure just different constants (e.g. 50 above is the constant values of that vertex.
Now here is the really weird part, the code above works as expected, but as soon as change the ratio "100/100" to anything below "99/100" or less, it behaves as if the code were:
float boxPosFactorX = (869-3)
float boxPosFactorY = (940-3)
99/100 is 0 (and 101/100 is exactly 1). That is integer arithmetic. If you want floating point arithmetic, use 99F/100.

Finding a percentage

Here's the problem. I have a picture that will have a different Height every time according to the picture that's loaded.
I'd like to scale that picture so it fits inside of the document which has 800 pixels height. So if the image has 2560px in height, I need to find out the PERCENTAGE needed to bring that pixel height down to 750 so it fits snuggly on the page.
I'm stuck trying to find the formula for this simple enough problem.
Here's my code:
iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(
image, System.Drawing.Imaging.ImageFormat.Jpeg);
if (pic.Height > pic.Width)
{
//Maximum height is 800 pixels.
pic.Height formula goes here....
}
else
{
//Maximum width is 600 pixels.
pic.Width formula goes here....
}
Some number p is such that p * 2560 = 750. Therefore, p = 750 / 2560 = 0.29296875.
Of course, make sure that you do floating-point division.
The rule of three will help you sort it out.
I don't know if I understand your problem exactly. Do you mean something like this?
percentage = (frameHeight / picHeight) * 100
Example:
(750 / 2560) * 100 = 29
That means: 2560 * 0.29 = 750
Here x is the maximum desired height, y is the actual image height and p is the percentage.
p = x / y;
x = p * y;
y = x / p;
Given any two you can find the other.

Categories