如何扩展下面的简单功能以确定预期的移动方向并锁定到该轴的移动?
换句话说,用户打算平移,但由于他们是人类,他们向下平移但略微向右平移,比例为6:1我如何推断预期方向并锁定它?
这是我简洁的小盘功能:
function onPan(e:TransformGestureEvent):void
{
e.target.x += e.offsetX;
e.target.y += e.offsetY;
}
答案 0 :(得分:2)
虽然Shaun Husain的建议很接近,但AS3中的姿势并没有提供起点和终点,据我所知。为了解决这个问题,我从GESTURE_PAN事件中抽取了5个触发点的样本,并使用Levenshtein距离计算的变量来确定预期的方向。以下是此问题的可行解决方案:
var onPanPointer:Number;
var onPanLevString:String;
var onPanLevSampleSize:Number;
onPanLevSampleSize = 5;
function onPan(e:TransformGestureEvent):void
{
if (Math.abs(e.offsetX) > Math.abs(e.offsetY))
{
// Looks like we intended to move on the X axis
if (e.offsetX > 0)
{
if (onPanLevString == null)
{
onPanLevString = "r"
}
else
{
onPanLevString = onPanLevString + "r"
}
}
else
{
if (onPanLevString == null)
{
onPanLevString = "l"
}
else
{
onPanLevString = onPanLevString + "l"
}
}
}
else
{
// Looks like we intended to move on the Y axis
if (e.offsetY > 0)
{
if (onPanLevString == null)
{
onPanLevString = "d"
}
else
{
onPanLevString = onPanLevString + "d"
}
}
else
{
if (onPanLevString == null)
{
onPanLevString = "u"
}
else
{
onPanLevString = onPanLevString + "u"
}
}
}
if (onPanPointer < onPanLevSampleSize)
{
onPanPointer += 1;
}
else
{
//trace("Pointer Value has reached the desired count of: " + onPanPointer);
//trace("The Levenshtein String is: " + onPanLevString);
if (levenshteinDistance(onPanLevString,repeatString("u",onPanLevSampleSize)) <= ((onPanLevSampleSize/2)+1))
{
e.target.y += e.offsetY*onPanLevSampleSize;
//trace("Panning Up");
}
else if (levenshteinDistance(onPanLevString,repeatString("d",onPanLevSampleSize)) <= ((onPanLevSampleSize/2)+1))
{
e.target.y += e.offsetY*onPanLevSampleSize;
//trace("Panning Down");
}
else if (levenshteinDistance(onPanLevString,repeatString("l",onPanLevSampleSize)) <= ((onPanLevSampleSize/2)+1))
{
e.target.x += e.offsetX*onPanLevSampleSize;
//trace("Panning Left");
}
else
{
e.target.x += e.offsetX*onPanLevSampleSize;
//trace("Panning Right");
}
onPanPointer = 1;
onPanLevString = null;
}
//trace("X Offset = " + e.offsetX);
//trace("Y Offset = " + e.offsetY);
}
正在使用的levenshteinDistance函数(如下所示)由mircea16在Snipplr上编写,可以是found here。
function levenshteinDistance(s1:String,s2:String):int
{
var m:int=s1.length;
var n:int=s2.length;
var matrix:Array=new Array();
var line:Array;
var i:int;
var j:int;
for (i=0;i<=m;i++)
{
line=new Array();
for (j=0;j<=n;j++)
{
if (i!=0)line.push(0)
else line.push(j);
}
line[0]=i
matrix.push(line);
}
var cost:int;
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
{
if (s1.charAt(i-1)==s2.charAt(j-1)) cost=0
else cost=1;
matrix[i][j]=Math.min(matrix[i-1][j]+1,matrix[i][j-1]+1,matrix[i-1][j-1]+cost);
}
return matrix[m][n];
}
您需要使上面的示例工作的最后一个函数是我使用的repeatString函数。 (这需要您使用onPanLevSampleSize var更改样本大小,而不必更改其他任何内容)
function repeatString(string:String, numTimes:uint):String
{
var output:String = "";
for(var i:uint = 0; i < numTimes; i++)
output += string;
return output;
}
您需要更改以调整所使用的样本大小的唯一数字是onPanLevSampleSize,所有计算都是使用该数字作为基础执行的。
希望这可以帮助将来的某个人!
答案 1 :(得分:1)
没有试过这个,但我认为他会更喜欢这样的事情:
private var startX:Number;
private var startY:Number;
private function onPan(e:TransformGestureEvent):void
{
var currentX:Number = e.localX;
var currentY:Number = e.localY;
if(Math.pow(currentX-startX,2) > Math.pow(currentY - startY,2))
{
e.target.x = currentX;
}
else
{
e.target.y = currentY;
}
}
我只是遗漏了你想要设置startX和startY的部分我还没有使用过TransformGestureEvent,但我认为它有一个初始的down事件你可以标记startX / startY。基本上我只是想看看X的变化是否大于Y的变化,如果这样调整X,否则调整Y.所以就像粘盘一样。
答案 2 :(得分:0)
奇怪的问题,但我想我明白你在寻找什么。
function onPan(e:TransformGestureEvent):void
{
e.target.x += e.offsetX + (e.offsetY/6); // use ratio from offsetY
e.target.y += e.offsetY;
}