速度が問題で、メモリ/ディスク容量がそうでない場合は、次のことを検討してください。これは可能な限り最も効率的な方法です。
このようにして、重要な計算を行う前に、いくつかの非常に高速なテストを実行できます。
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 時間睡眠をとったので、校正はしません。いくつかのマイナーな修正を行う必要がある場合があります。または主要なもの。知るか。:)