-2

My app gives the distance between 2 points made on a picturebox. Previously they were doing this by hand and wanted an app to do it. However when you make the line, the distance for that line using the below formula for even a small line for example is 30 However when you use a ruler with 1/32 on it, the measurement is 5/32.

So what is 30? What type of distance is used here and how do I convert this to display the number as it would using a ruler with 1/32 measurement?

//Distance between 2 points.
//     ______________________
//d = √ (x2-x1)^2 + (y2-y1)^2     

dist = (Convert.ToInt32(Math.Sqrt(Math.Pow(Math.Abs(p2List[i].X - p1List[i].X), 2) + Math.Pow(Math.Abs(p2List[i].Y - p1List[i].Y), 2))));

So here's what I've done.

            Vector2 src = new Vector2(p1List[i].X, p1List[i].Y); //first point on the image
            Vector2 dst = new Vector2(p2List[i].X, p2List[i].Y); //second point on the image
            float Density = 38;
            Vector2 dif = dst - src;  //difference between the vectors
            float len = dif.Length(); //length of the vector, in this case the distance in pixels
            float inchLen = len / Density; //density is a float with the image DPI's

            DataGridViewRow row = dataGridView1.Rows[rowId];
            row.Cells["colLength"].Value = inchLen;

This, for the little line I made, gives me 0.7649706 But I don't know how to make that say a 3,5,6 or whatever it would be if measured using the 1/32 on a ruler.

Lee
  • 133
  • 11
  • 2
    If your points positions are in pixels, then you need to convert distance in pixels to inches – Markiian Benovskyi Jan 23 '17 at 11:40
  • 2
    And since they are intergers you need to convert to float/double to avoid integer math errors. – TaW Jan 23 '17 at 11:41
  • Use the library System.Numerics and the Vector2 class, it already has the Length function implemented with hardware acceleration. – Gusman Jan 23 '17 at 11:46

1 Answers1

1

It strictly depends on the image. The unit you have is pixels, so the result is that, distance in pixels. To convert to inches you need to know the image's density, if it's a regular image they usually are at 72dpi or 96dpi, but I will assume these are for some type of printing or like that, so these will vary from 300dpi to any density, you need to know this before computing the distance.

So if per example, you have an image with 72dpi and you get a distance of 30, then the distance in inches will be 30/72 wich are 0.42 inches.

Don't use integer arithmetic, this will cause a ton of errors, you need the decimals at the result to get an accurate measuring, use at least a float, and if the precission must be very high then use doubles.

Also, instead of using manually the Math class use the System.Numerics nuget package, it's hardware accelerated and has a ton of functions related to vector manipulation, per example for your task you can do:

Vector2 src = new Vector2(srcX, srcY); //first point on the image
Vector2 dst = new Vector2(dstX, dstY); //second point on the image

Vector2 dif = dst - src;  //difference between the vectors

float len = dif.Length(); //length of the vector, in this case the distance in pixels

float inchLen = len / Density; //density is a float with the image DPI's
Gusman
  • 14,905
  • 2
  • 34
  • 50
  • Check my update out. How do I convert this number now to whatever the 1/32 would be. Is it 1 for 1/32? Is it 5 for 5/32? Not sure what to do here. – Lee Jan 23 '17 at 12:42
  • what is "1/32"? you mean 1/32 inches? If that's the case then multiply the result by 32 as the result you have is already in inches. – Gusman Jan 23 '17 at 12:45
  • Also, you set the density to "38", that value must be wrong for sure, where you got that value? – Gusman Jan 23 '17 at 12:48
  • I made a very small line and multiplied the result by 32 and I get `19.4321`. I used `float finaldist = inchLen * 32;` But that number is still way to large. I got that value in paint shop pro. I looked up how to find the dpi. Actually it may be 96 let me try that. I changed the resolution to pixels / inch. – Lee Jan 23 '17 at 12:49
  • Ok so I changed the density to 96 which is what it shows in PSP as the resolution Pixels / Inch. And now my tiny line is even larger at `60.631` – Lee Jan 23 '17 at 12:52
  • I think I figured it out finally but I need `float finaldist = inchLen * 32;` to be a whole number. I've tried converting it to an `int` but then I just get a `0` for everything. – Lee Jan 23 '17 at 13:09
  • well, if the distance is less than 1/32 and you cast it to int then for sure the return will be 0, what you expect it to be? The most you can get is Math.Round which will round to the nearest integer. Update your code with the final one to see if there's something else wrong. – Gusman Jan 23 '17 at 13:11
  • I was just typing a response when I saw your post. I did this `double finaldist = Math.Round(inchLen * 32);` and the numbers finally look like what I'd expect but I wanted to make sure that was correct. – Lee Jan 23 '17 at 13:15