答案 0 :(得分:1)
答案 1 :(得分:1)
我想出了“反复试验”的方法:Full example
// Returns item.position at the moment of collision
// and the collided object.
function collisionTest(item, curr){
var prev = item.position;
var point = curr.clone();
var hit = null;
var tolerance = 45;
var _error = 0.01;
var firstPass = true;
var _stopSearching = false;
var _step = ((curr - prev) / 2).clone();
var _acceptable_iter_count = 16;
var _max_iter_count = 100;
var i;
for (i = 0; i < _max_iter_count; i++){
var _hit = project.hitTest(point, {
fill: true,
stroke: true,
segments: true,
tolerance: tolerance,
match: function(hit){
if (hit.item && hit.item.data && hit.item.data.type === "pointer"){
return false
}
return true
}
})
if(_hit){
hit = _hit;
// hit has happened between prev and curr points
// step half way backward
point -= _step
if (_step.length < _error){
// step is too small, stop trials as soon
// as no hit can be found
_stopSearching = true;
}
} else {
if(firstPass || _stopSearching){
break;
} else {
// not hit found, but we should
// step forward to search for a more
// accurate collision point
point += _step
}
}
firstPass = false;
if(_step.length >= _error * 2 ) {
_step /= 2
} else {
// minimum step length must be error/2
// in order to save loop count
_step = _step.normalize(_error * 0.8)
}
}
if (i > _acceptable_iter_count){
console.log("found at " + i + ". iteration, step: ", _step.length)
}
return {point, hit}
}
delta
上)的任何地方。 delta = delta / 2
并执行一次命中测试。 delta = delta / 2
delta
)太小或过程超出了最大迭代限制,请中断并返回可能的最佳碰撞点(该项目提供最佳碰撞点的点)此解决方案基于以下问题:检测不到一个碰撞,因为检测到碰撞可能为时已晚,并且在先前点与当前点之间的任何地方都可能发生实际碰撞( (delta
上的点击次数)。
可以通过在检测到第一个击中之后基于适当的计算进行非常准确的“猜测”的尝试来改进这种反复试验的方法。
我们可以使用1
一杆计算2
(实际碰撞点)。似乎是3
到4
的最近点:
如果计算正确,则仅2个循环就足以检测到碰撞点:第一个用于检测碰撞(如#2
所示),第二个用于验证。如果不正确,将采用试错法。
答案 2 :(得分:0)
您可以尝试从移动点的位置开始在路径上找到nearest point。而不是尝试查找直接相交。
如果点和最近点之间的距离下降到阈值以下(等于strokeWidth
的{{1}}和点的半径),则可以认为它是有效命中。
有一个问题:您路径的strokeJoin
和strokeCap
属性应为
设置为Path
,因为这会导致围绕的对称笔划宽度
拐角和结尾,因此避免了假阴性。
这是一个例子:
round
和Sketch。
话虽如此,最好的方法是等待{或执行自己)Path dilation/offsetting并在膨胀路径上找到交点,因为这将允许您使用任何{{1 }} / var path = new Path({
segments: [
new Point(100, 200),
new Point(200, 100),
new Point(300, 300)
],
strokeWidth: 100,
// This is important.
strokeJoin: 'round',
// This is important.
strokeCap: 'round',
strokeColor: 'red',
selected: true,
position: view.center
})
var dot = new Path.Circle({
center: view.center,
radius: 10,
fillColor: 'red'
})
function onMouseMove(event) {
dot.position = event.point
var nearestPoint = path.getNearestPoint(dot.position)
var distance = dot.position.subtract(nearestPoint)
if (distance.length < (dot.bounds.width / 2) + (path.strokeWidth / 2)) {
path.strokeColor = 'blue'
} else {
path.strokeColor = 'red'
}
}
设置。
理想情况下,将使用与strokeJoin
相同的strokeCap
/ strokeJoin
属性进行膨胀/抵消。