Actionscript 3 在Actionscript 3中查找前3个最近的目标

Actionscript 3 在Actionscript 3中查找前3个最近的目标,actionscript-3,actionscript,Actionscript 3,Actionscript,我有一个点字符数组,我想取任何字符,并能够循环通过该数组,找到前3个最近的(使用Point.distance)邻居。有人能告诉我怎么做吗?这是我昨晚发布的代码的一个新的改进版本。它由两个类组成,PointTester和TestCase。这一次我也能测试它了 我们从TestCase.as开始 package { import flash.geom.Point; import flash.display.Sprite; public class TestCase ext

我有一个点字符数组,我想取任何字符,并能够循环通过该数组,找到前3个最近的(使用Point.distance)邻居。有人能告诉我怎么做吗?

这是我昨晚发布的代码的一个新的改进版本。它由两个类组成,PointTester和TestCase。这一次我也能测试它了

我们从TestCase.as开始

package  {

    import flash.geom.Point;
    import flash.display.Sprite;

    public class TestCase extends Sprite {

        public function TestCase() {
            // some data to test with
            var pointList:Array = new Array();
            pointList.push(new Point(0, 0));
            pointList.push(new Point(0, 0));
            pointList.push(new Point(0, 0));
            pointList.push(new Point(1, 2));
            pointList.push(new Point(9, 9));

            // the point we want to test against
            var referencePoint:Point = new Point(10, 10);

            var resultPoints:Array = PointTester.findClosest(referencePoint, pointList, 3);

            trace("referencePoint is at", referencePoint.x, referencePoint.y);
            for each(var result:Object in resultPoints) {
                trace("Point is at:", result.point.x, ", ", result.point.y, " that's ", result.distance, " units away");
            }
        }

    }

}
package  {

    import flash.geom.Point;

    public class PointTester {

        public static function findClosest(referencePoint:Point, pointList:Array, maxCount:uint = 3):Array{

            // this array will hold the results
            var resultList:Array = new Array();

            // loop over each point in the test data
            for each (var testPoint:Point in pointList) {

                // we store the distance between the two in a temporary variable
                var tempDistance:Number = getDistance(testPoint, referencePoint);

                // if the list is shorter than the maximum length we don't need to do any distance checking
                // if it's longer we compare the distance to the last point in the list, if it's closer we add it
                if (resultList.length <= maxCount || tempDistance < resultList[resultList.length - 1].distance) {

                    // we store the testing point and it's distance to the reference point in an object
                    var tmpObject:Object = { distance : tempDistance, point : testPoint };
                    // and push that onto the array
                    resultList.push(tmpObject);

                    // then we sort the array, this way we don't need to compare the distance to any other point than
                    // the last one in the list
                    resultList.sortOn("distance", Array.NUMERIC );

                    // and we make sure the list is kept at at the proper number of entries
                    while (resultList.length > maxCount) resultList.pop();
                }
            }

            return resultList;
        }

        public static function getDistance(point1:Point, point2:Point):Number {
            var x:Number = point1.x - point2.x;
            var y:Number = point1.y - point2.y;
            return Math.sqrt(x * x + y * y);
        }
    }
}
这将是PointTester.as

package  {

    import flash.geom.Point;
    import flash.display.Sprite;

    public class TestCase extends Sprite {

        public function TestCase() {
            // some data to test with
            var pointList:Array = new Array();
            pointList.push(new Point(0, 0));
            pointList.push(new Point(0, 0));
            pointList.push(new Point(0, 0));
            pointList.push(new Point(1, 2));
            pointList.push(new Point(9, 9));

            // the point we want to test against
            var referencePoint:Point = new Point(10, 10);

            var resultPoints:Array = PointTester.findClosest(referencePoint, pointList, 3);

            trace("referencePoint is at", referencePoint.x, referencePoint.y);
            for each(var result:Object in resultPoints) {
                trace("Point is at:", result.point.x, ", ", result.point.y, " that's ", result.distance, " units away");
            }
        }

    }

}
package  {

    import flash.geom.Point;

    public class PointTester {

        public static function findClosest(referencePoint:Point, pointList:Array, maxCount:uint = 3):Array{

            // this array will hold the results
            var resultList:Array = new Array();

            // loop over each point in the test data
            for each (var testPoint:Point in pointList) {

                // we store the distance between the two in a temporary variable
                var tempDistance:Number = getDistance(testPoint, referencePoint);

                // if the list is shorter than the maximum length we don't need to do any distance checking
                // if it's longer we compare the distance to the last point in the list, if it's closer we add it
                if (resultList.length <= maxCount || tempDistance < resultList[resultList.length - 1].distance) {

                    // we store the testing point and it's distance to the reference point in an object
                    var tmpObject:Object = { distance : tempDistance, point : testPoint };
                    // and push that onto the array
                    resultList.push(tmpObject);

                    // then we sort the array, this way we don't need to compare the distance to any other point than
                    // the last one in the list
                    resultList.sortOn("distance", Array.NUMERIC );

                    // and we make sure the list is kept at at the proper number of entries
                    while (resultList.length > maxCount) resultList.pop();
                }
            }

            return resultList;
        }

        public static function getDistance(point1:Point, point2:Point):Number {
            var x:Number = point1.x - point2.x;
            var y:Number = point1.y - point2.y;
            return Math.sqrt(x * x + y * y);
        }
    }
}
包{
导入flash.geom.Point;
公共类点测试器{
公共静态函数findClosest(referencePoint:Point,pointList:Array,maxCount:uint=3):数组{
//此数组将保存结果
var resultList:Array=new Array();
//循环测试数据中的每个点
对于每个(var测试点:点列表中的点){
//我们将两者之间的距离存储在一个临时变量中
var tempDistance:Number=getDistance(测试点、参考点);
//如果列表短于最大长度,我们不需要进行任何距离检查
//如果距离更长,我们将其与列表中的最后一个点进行比较,如果距离更近,我们将其添加
if(resultList.length maxCount)resultList.pop();
}
}
返回结果列表;
}
公共静态函数getDistance(点1:点,点2:点):编号{
变量x:Number=point1.x-point2.x;
变量y:Number=point1.y-point2.y;
返回Math.sqrt(x*x+y*y);
}
}
}

值得一提的是,如果点数足够大,足以使性能变得重要,那么可以通过保留两个点数列表更快地实现目标,一个按X排序,另一个按Y排序。然后可以在O(logn)时间内找到最接近的3个点数,而不是O(n)通过循环通过每个点来计算时间。

如果使用grapefrukt的解决方案,可以将getDistance方法更改为
返回x*x+y*y
而不是
返回Math.sqrt(x*x+y*y)

您将原始点存储在tmpObject中,但以后不再使用它,这会不会是一个问题?实际上我只是用它来获取两点之间的距离,新版本有它自己的功能。