आप निम्न खोजने की जरूरत है:
- निकटतम कोने से दूरी
- निकटतम किनारे से दूरी
- (वैकल्पिक) के केंद्र के लिए
मूल रूप से दूर है, तो आप इन तीन मूल्यों के छोटे से चाहते हैं। यह निर्धारित करने के लिए कि कौन सा करीब है, उसके नियंत्रण को दो नियंत्रणों में लें।
जब आप फ़ॉर्म पर सभी नियंत्रणों को पुन: स्थापित करके फॉर्म को लोड करते हैं और नीचे दिए गए वर्ग का संग्रह बनाते हैं तो शुरू करें।
किसी बिंदु पर सबसे नज़दीकी नियंत्रण ढूंढने के लिए, संग्रह को पुन: सक्रिय करें (नीचे कोड देखें)। अब तक की न्यूनतम दूरी के साथ नियंत्रण का ट्रैक रखें। यदि आप चाहते हैं तो आप ContainsPoint() के लिए परीक्षण कर सकते हैं ... यदि आपको नियंत्रण मिलता है जहां बिंदु नियंत्रण सीमाओं के भीतर आता है, तो आपको अपना नियंत्रण मिल जाता है (जब तक आपके पास ओवरलैपिंग नियंत्रण नहीं है)। अन्यथा, जब आप संग्रह के अंत तक पहुंच जाते हैं, तो केंद्र/किनारे की सबसे छोटी दूरी के साथ आपको जो नियंत्रण मिलता है वह आपका नियंत्रण होता है।
public class HitControl {
public Control ThisControl;
private Rectangle ControlBounds;
private Point Center;
public HitControl (Control FormControl) {
ControlBounds = FormControl.Bounds;
Center = new Point(ControlBounds.X + (ControlBounds.Width/2), ControlBounds.Y + (ControlBounds.Height/2));
}
// Calculate the minimum distance from the left, right, and center
public double DistanceFrom(Point TestPoint) {
// Note: You don't need to consider control center points unless
// you plan to allow for controls placed over other controls...
// Then you need to test the distance to the centers, as well,
// and pick the shortest distance of to-edge, to-side, to-corner
bool withinWidth = TestPoint.X > ControlBounds.X && TestPoint.X < ControlBounds.X + ControlBounds.Width;
bool withinHeight = TestPoint.Y > ControlBounds.Y && TestPoint.Y < ControlBounds.Y + ControlBounds.Height;
int EdgeLeftXDistance = Math.Abs(ControlBounds.X - TestPoint.X);
int EdgeRightXDistance = Math.Abs(ControlBounds.X + ControlBounds.Width - TestPoint.X);
int EdgeTopYDistance = Math.Abs(ControlBounds.Y - TestPoint.Y);
int EdgeBottomYDistance = Math.Abs(ControlBounds.Y + ControlBounds.Height - TestPoint.Y);
int EdgeXDistance = Math.Min(EdgeLeftXDistance, EdgeRightXDistance);
int EdgeYDistance = Math.Min(EdgeTopYDistance, EdgeBottomYDistance);
// Some points to consider for rectangle (100, 100, 100, 100):
// - (140, 90): Distance to top edge
// - (105, 10): Distance to top edge
// - (50, 50): Distance to upper left corner
// - (250, 50): Distance to upper right corner
// - (10, 105): Distance to left edge
// - (140, 105): Distance to top edge
// - (105, 140): Distance to left edge
// - (290, 105): Distance to right edge
// - (205, 150): Distance to right edge
// ... and so forth
// You're within the control
if (withinWidth && withinHeight) {
return Math.Min(EdgeXDistance, EdgeYDistance);
}
// You're above or below the control
if (withinWidth) {
return EdgeYDistance;
}
// You're to the left or right of the control
if (withinHeight) {
return EdgeXDistance;
}
// You're in one of the four outside corners around the control.
// Find the distance to the closest corner
return Math.Sqrt(EdgeXDistance^2 + EdgeYDistance^2);
}
public bool ContainsPoint (Point TestPoint) {
return ControlBounds.Contains(TestPoint);
}
}
// Initialize and use this collection
List<HitControl> hitControls = (from Control control in Controls
select new HitControl(control)).ToList();
Point testPoint = new Point(175, 619);
double distance;
double shortestDistance = 0;
HitControl closestControl = null;
foreach (HitControl hitControl in hitControls) {
// Optional... works so long as you don't have overlapping controls
// If you do, comment this block out
if (hitControl.ContainsPoint(testPoint)) {
closestControl = hitControl;
break;
}
distance = hitControl.DistanceFrom(testPoint);
if (shortestDistance == 0 || distance < shortestDistance) {
shortestDistance = distance;
closestControl = hitControl;
}
}
if (closestControl != null) {
Control foundControl = closestControl.ThisControl;
}
स्रोत
2010-10-19 14:48:50
क्या उनमें से एक उत्तर आपकी मदद करता है? –