PDA

View Full Version : سوال: بدست آوردن فاصله بین دو نقطه که با موس کلیک می شود



morteza271
یک شنبه 26 دی 1389, 12:21 عصر
سلام دوستان.

من توی برنامم یه فرم دارم که کاربر میتونه یه عکس از هارد سیستمش انتخاب کنه، و برنامه عکس رو در یه PictureBox نشون میده.
حالا کاربر میخواد فاصله دو نقطه از عکس رو پیدا کنه، برای این کار روی نقطه اول کلیک میکنه و سپس روی نقطه دوم. حالا برنامه باید فاصله این دو نقطه که با موس کلیک میشه رو خیلی دقیق(در حد میکرو) بدست بیاره و نشون بده!
از دوستان خواهش میکنم اگه کسی نمونه کدی یا برنامه ای داره برام بذاره.
با کمال تشکر:قلب:
(البته باید بگم که حتما این دو نقطه عمودی یا افقی نیستن و ممکنه ضربدری و یا به هر صورت دیگری باشن!)

morteza271
یک شنبه 26 دی 1389, 20:41 عصر
دوستان كسي نيس جواب بده!
خواهشا كمك كنيد.
يه سوال ديگه اين Location كه توي خود سي شارپ داره برحسب چيه؟!
چجوري ميشه به سانتي متر تبديلش كرد؟
دوستان خواهشا سريعتر جواب بدين خيلي لازمش دارم.
با تشكر...

shuriken
دوشنبه 27 دی 1389, 10:29 صبح
شما برای اینکار باید رخداد mousbuttonclick از کنترل picturebox رو handle کنی
و در اون هربار کاربر روی کنترل کلیک کرد از شی e که خود vs ایجاد میکنه استفاده کنی
و بوسیله فرمولهای ریاضی و با استفاده از کلاس math فاصله بین بقاط رو بدست بیاری

اگه خودت نتونستی کاریش کنی بم بگو تا بیشتر کمکت کنم

morteza271
دوشنبه 27 دی 1389, 10:36 صبح
ممنونم دوست عزيز.
فاصله اي كه خود سي شارپ ميده برحسب چيه؟من شنيدم Pixcel هستش كه تبديل اون به سانتي متر سخته چون روي هر كامپيوتر فرق ميكنه!!!درسته؟
اگه ميشه بيشتر راهنمايي كنيد و اگه يه نمونه كد و يا برنامه اي دارين برام بذارين.
با تشكر...

jeson_park
دوشنبه 27 دی 1389, 10:46 صبح
سلام
ببنید این تابع به درد شما می خوره یا نه؟


void DistanceFromLine(double cx, double cy, double ax, double ay ,
double bx, double by, double &distanceSegment,
double &distanceLine)
{

double r_numerator = (cx-ax)*(bx-ax) + (cy-ay)*(by-ay);
double r_denomenator = (bx-ax)*(bx-ax) + (by-ay)*(by-ay);
double r = r_numerator / r_denomenator;
//
double px = ax + r*(bx-ax);
double py = ay + r*(by-ay);
//
double s = ((ay-cy)*(bx-ax)-(ax-cx)*(by-ay) ) / r_denomenator;
distanceLine = fabs(s)*sqrt(r_denomenator);
//
// (xx,yy) is the point on the lineSegment closest to (cx,cy)
//
double xx = px;
double yy = py;
if ( (r >= 0) && (r <= 1) )
{
distanceSegment = distanceLine;
}
else
{
double dist1 = (cx-ax)*(cx-ax) + (cy-ay)*(cy-ay);
double dist2 = (cx-bx)*(cx-bx) + (cy-by)*(cy-by);
if (dist1 < dist2)
{
xx = ax;
yy = ay;
distanceSegment = sqrt(dist1);
}
else
{
xx = bx;
yy = by;
distanceSegment = sqrt(dist2);
}

}
return;
}

این هم یه برنامه که تحت کنسول هست
الان ویژوال سی شارپ نصب شده ندارم وگرنه برات تبدیلش میکردم


using System;
using System.Text;
public class CDistanceBetweenLocations
{
public static double Calc(double Lat1,
double Long1, double Lat2, double Long2)
{
/*


dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = R * c

Where
* dlon is the change in longitude
* dlat is the change in latitude
* c is the great circle distance in Radians.
* R is the radius of a spherical Earth.
* The locations of the two points in
spherical coordinates (longitude and
latitude) are lon1,lat1 and lon2, lat2.
*/
double dDistance = Double.MinValue;
double dLat1InRad = Lat1 * (Math.PI / 180.0);
double dLong1InRad = Long1 * (Math.PI / 180.0);
double dLat2InRad = Lat2 * (Math.PI / 180.0);
double dLong2InRad = Long2 * (Math.PI / 180.0);
double dLongitude = dLong2InRad - dLong1InRad;
double dLatitude = dLat2InRad - dLat1InRad;
// Intermediate result a.
double a = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) +
Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) *
Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);
// Intermediate result c (great circle distance in Radians).
double c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));
// Distance.
// const Double kEarthRadiusMiles = 3956.0;
const Double kEarthRadiusKms = 6376.5;
dDistance = kEarthRadiusKms * c;
return dDistance;
}
public static double Calc(string NS1, double Lat1, double Lat1Min,
string EW1, double Long1, double Long1Min, string NS2,
double Lat2, double Lat2Min, string EW2,
double Long2, double Long2Min)
{
double NS1Sign = NS1.ToUpper() == "N" ? 1.0 : -1.0;
double EW1Sign = NS1.ToUpper() == "E" ? 1.0 : -1.0;
double NS2Sign = NS2.ToUpper() == "N" ? 1.0 : -1.0;
double EW2Sign = EW2.ToUpper() == "E" ? 1.0 : -1.0;
return (Calc(
(Lat1 + (Lat1Min / 60)) * NS1Sign,
(Long1 + (Long1Min / 60)) * EW1Sign,
(Lat2 + (Lat2Min / 60)) * NS2Sign,
(Long2 + (Long2Min / 60)) * EW2Sign
));
}
public static void Main(string[] args)
{
if (args.Length < 12)
{
System.Console.WriteLine("usage: DistanceBetweenLocations" +
" N 43 35.500 W 80 27.800 N 43 35.925 W 80 28.318");
return;
}
System.Console.WriteLine(Calc(
args[0],
System.Double.Parse(args[1]),
System.Double.Parse(args[2]),
args[3],
System.Double.Parse(args[4]),
System.Double.Parse(args[5]),
args[6],
System.Double.Parse(args[7]),
System.Double.Parse(args[8]),
args[9],
System.Double.Parse(args[10]),
System.Double.Parse(args[11])));
}
}


موفق باشید

morteza271
دوشنبه 27 دی 1389, 10:55 صبح
سلام
ببنید این تابع به درد شما می خوره یا نه؟


void DistanceFromLine(double cx, double cy, double ax, double ay ,
double bx, double by, double &distanceSegment,
double &distanceLine)
{

double r_numerator = (cx-ax)*(bx-ax) + (cy-ay)*(by-ay);
double r_denomenator = (bx-ax)*(bx-ax) + (by-ay)*(by-ay);
double r = r_numerator / r_denomenator;
//
double px = ax + r*(bx-ax);
double py = ay + r*(by-ay);
//
double s = ((ay-cy)*(bx-ax)-(ax-cx)*(by-ay) ) / r_denomenator;
distanceLine = fabs(s)*sqrt(r_denomenator);
//
// (xx,yy) is the point on the lineSegment closest to (cx,cy)
//
double xx = px;
double yy = py;
if ( (r >= 0) && (r <= 1) )
{
distanceSegment = distanceLine;
}
else
{
double dist1 = (cx-ax)*(cx-ax) + (cy-ay)*(cy-ay);
double dist2 = (cx-bx)*(cx-bx) + (cy-by)*(cy-by);
if (dist1 < dist2)
{
xx = ax;
yy = ay;
distanceSegment = sqrt(dist1);
}
else
{
xx = bx;
yy = by;
distanceSegment = sqrt(dist2);
}

}
return;
}

این هم یه برنامه که تحت کنسول هست
الان ویژوال سی شارپ نصب شده ندارم وگرنه برات تبدیلش میکردم


using System;
using System.Text;
public class CDistanceBetweenLocations
{
public static double Calc(double Lat1,
double Long1, double Lat2, double Long2)
{
/*


dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = R * c

Where
* dlon is the change in longitude
* dlat is the change in latitude
* c is the great circle distance in Radians.
* R is the radius of a spherical Earth.
* The locations of the two points in
spherical coordinates (longitude and
latitude) are lon1,lat1 and lon2, lat2.
*/
double dDistance = Double.MinValue;
double dLat1InRad = Lat1 * (Math.PI / 180.0);
double dLong1InRad = Long1 * (Math.PI / 180.0);
double dLat2InRad = Lat2 * (Math.PI / 180.0);
double dLong2InRad = Long2 * (Math.PI / 180.0);
double dLongitude = dLong2InRad - dLong1InRad;
double dLatitude = dLat2InRad - dLat1InRad;
// Intermediate result a.
double a = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) +
Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) *
Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);
// Intermediate result c (great circle distance in Radians).
double c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));
// Distance.
// const Double kEarthRadiusMiles = 3956.0;
const Double kEarthRadiusKms = 6376.5;
dDistance = kEarthRadiusKms * c;
return dDistance;
}
public static double Calc(string NS1, double Lat1, double Lat1Min,
string EW1, double Long1, double Long1Min, string NS2,
double Lat2, double Lat2Min, string EW2,
double Long2, double Long2Min)
{
double NS1Sign = NS1.ToUpper() == "N" ? 1.0 : -1.0;
double EW1Sign = NS1.ToUpper() == "E" ? 1.0 : -1.0;
double NS2Sign = NS2.ToUpper() == "N" ? 1.0 : -1.0;
double EW2Sign = EW2.ToUpper() == "E" ? 1.0 : -1.0;
return (Calc(
(Lat1 + (Lat1Min / 60)) * NS1Sign,
(Long1 + (Long1Min / 60)) * EW1Sign,
(Lat2 + (Lat2Min / 60)) * NS2Sign,
(Long2 + (Long2Min / 60)) * EW2Sign
));
}
public static void Main(string[] args)
{
if (args.Length < 12)
{
System.Console.WriteLine("usage: DistanceBetweenLocations" +
" N 43 35.500 W 80 27.800 N 43 35.925 W 80 28.318");
return;
}
System.Console.WriteLine(Calc(
args[0],
System.Double.Parse(args[1]),
System.Double.Parse(args[2]),
args[3],
System.Double.Parse(args[4]),
System.Double.Parse(args[5]),
args[6],
System.Double.Parse(args[7]),
System.Double.Parse(args[8]),
args[9],
System.Double.Parse(args[10]),
System.Double.Parse(args[11])));
}
}


موفق باشید

ممنونم ولي ميشه تابع رو يه خورده توضيح بدين؟!
الان نميتونم تست كنم ولي به زودي تست ميكنم و خبرشو ميدم!
از بقيه دوستان هم خواهش ميكنم اگه نظري دارن دريغ نكنن و نظرشون رو بگن.
با تشكر...

shuriken
دوشنبه 27 دی 1389, 11:47 صبح
اینکار در هر مانیتور مسلما فرق میکنه و شما برای اینکه بتونی این تبدیل رو انجام بدی باید
اول اطلاعاتی در مورد اون نمایشگر ( که حتی میتونه پرینتر باشه) بدست بیاری.
مثلا dpi مربوط به اون display رو. یا رزلوشنش رو.
بعد تبدیلترو انجام بدی
کد زیر تبدیل پیکسل به نقاط


Graphics g = this.CreateGraphics();
points = pixels * 72 / g.DpiX;
g.Dispose();

شما وقتی تعداد نقطرو داشته باشی میتونی با استفاده از dpi به سانتیمتر تبدیلش کنی
هر اینچ 2.54 سانتیمتره