如果速度是一个问题但内存/磁盘空间不是问题,请考虑执行以下操作,这应该是最有效的方法。
通过这种方式,您可以在进行任何重要的数学运算之前执行一些非常快速的测试:
public class DataPoint
{
double X, Y;
...
}
public bool IsInBoundingBox(Point p1, Point p2, Point p3, Point p4)
{
// assume p1, p2, p3, p4 to be sorted
return (X>p1.X && X<p3.X && Y>p4.Y && Y<p2.Y);
}
那么实际工作的顺序应该是这样的......
// sort points of QueryRectangle: p1 is left-most, p2 is top-most, p3 is right-
// most, and p4 to be bottom-most; if there is a tie for left-most, p1 should
// be the bottom-left corner, p2 the top-left corner, p3 the top-right corner,
// and p4 the bottom-right corner
// See if the QueryRectangle in question is aligned with the grid; if it is,
// then the set of DataPoints that lie within the BoundingBox are within the
// QueryRectangle and no further calculation is needed
if (p1.X == p2.X || p1.X == p3.X || p1.X == p4.X)
{
// is orthogonal (aligned with axes)
foreach(DataPoint dp in listDataPoints)
if(dp.IsInBoundingBox())
{
// dp is in QueryRectangle; perform work
}
}
else
{
foreach(DataPoint dp in listDataPoints)
if(dp.IsInBoundingBox())
{
// perform further testing to see if dp is in QueryRectangle
}
}
或者,如果您想使用 viraptor 建议的旋转/平移解决方案...
// sort points of QueryRectangle: p1 is left-most, p2 is top-most, p3 is right-
// most, and p4 to be bottom-most; if there is a tie for left-most, p1 should
// be the bottom-left corner, p2 the top-left corner, p3 the top-right corner,
// and p4 the bottom-right corner
public class DataPointList : List<DataPoint>
{
public List<DataPoint> GetPointsInRectangle(Point p1, Point p2, Point p3, Point p4)
{
List<DataPoint> tempListDataPoints = new List<DataPoint>();
foreach(DataPoint dp in this)
if(dp.IsInBoundingBox()) tempListDataPoints.Add(dp);
if (!(p1.X == p2.X || p1.X == p3.X || p1.X == p4.X))
{
// needs transformation
tempListDataPoints.TranslateAll(-1 * p1.X, -1 * p1.Y);
tempListDataPoints.RotateAll(/* someAngle derived from the arctan of p1 and p2 */);
// Note: you should be rotating counter-clockwise by some angle >0 but <90
// the new p1 will be 0,0, but p2, p3, and p4 all need to undergo the same transformations
// transP1 = new Point(0,0);
// transP2 = new Point(p2.Translate(-1 * p1.X, -1 * p1.Y).Rotate(/* someAngle derived from the arctan of p1 and p2 */));
// transP3 = ...; transP4 = ...;
foreach(DataPoint dp in tempListDataPoints)
if (!(dp.X>transP1.X && dp.X<transP3.X && dp.Y>transP1.Y && dp.Y<transP3.Y)) tempListDataPoints.Remove(dp);
}
else
{
// QueryRectangle is aligned with axes, all points in bounding box
// lie within the QueryRectangle, no need for transformation or any
// further calculation
// no code needs to go here, but you may want to keep it around for notes
}
return tempListDataPoints;
}
}
或者,您可以使用数组执行上述代码。我会留给你解决这个问题...
免责声明:我昨晚睡了 2 个小时,所以我不会校对。您可能需要做一些小修复。或者主要的。谁知道。:)