距离画在画布上
<html>
<body style="margin:10px;">
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
</canvas>
</body>
<script language="javascript" type="text/javascript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = 400;
var centerY = 400;
var radius = .5;
context.beginPath(400,400);
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#003300';
context.stroke();
context.beginPath();
context.moveTo(50, 250);
context.bezierCurveTo(50, 250, 50, 250, 50, 250);
context.bezierCurveTo(90, 210, 90, 210, 90, 210);
context.bezierCurveTo(130, 90, 130, 90, 130, 90);
context.bezierCurveTo(260, 240, 260, 240, 260, 240);
context.bezierCurveTo(255, 400, 255, 400, 255, 400);
context.closePath();
context.lineWidth = 1;
context.strokeStyle = 'green';
context.stroke();
</script>
\t
\t
\t
\t
</html>
第一次张贴在这里,但这个网站已经帮助了我很多与其他灰色地带我有!
我想确定从画布上的点到形状边缘的距离。形状将是不规则的,例如,如果它的三角形我不认为如果距离公式超出三角形的边缘,它将不起作用。
我有点沮丧,因为这可能是我的项目的垮台。任何开放的想法,将不胜感激!
谢谢
编辑:这里就是我说的,在这个例子中,我想知道这是多少像素从共同ORD 400,400对象的最近点的例子。但对于我的项目,无论这个点在哪里,我都希望能够测量到物体的最近点。
我知道这是很多要问,但我想我会给它一个镜头!
感谢您提前回复!
这个问题的范围对于我来说写很多解决方案。我将概述如何添加一些限制。
形状是一组弧形,线条,曲线(立方体和二次方)以及矩形,它们可以连接也可以不连接。距离将是定义每个形状的线上最近的点,并且不包括线宽。形状都在相同的规模和方向。
最好的方法是使用MarkE指出的距离线功能(在他的评论“find the least distance from the point”中)并将所有路径对象转换为线。如何细分每条曲线将决定位置的准确度,直线不需要细分。但假设你只是在一个像素之后(鼠标分辨率),那么代码就不会做太多的处理。
您可以将行定义为点集。由于您可能有未加入的路径,所以这些点集将位于二维数组中。
var lines = [];
var currentLine = null;
function startLine(){
if(currentLine.length > 0){
currentLine = []; // new array
lines.push(cuurentLine); // push onto the line array
}
}
function moveToPoint(x,y){
startLine();
addPoint(x,y);
}
function addPoint(x,y){
currentLine.push(x:x,y:y);
}
function closePath(){
currentLine.push(currentLine[0]);
}
然后你就可以匹配调用上述功能
所有渲染调用一个最简单的一组线
ctx.beginPath();
ctx.moveTo(x,y); // to save me time x and y are points of some coordinate.
ctx.lineTo(x,y);
ctx.lineTo(x,y);
ctx.lineTo(x,y);
ctx.closePath();
应与
startLine(); // you really only need moveToPoint
moveToPoint(x,y);
addPoint(x,y);
addPoint(x,y);
addPoint(x,y);
closePath();
匹配
您的阵列应该看起来像
// p represents a point {x :x,y: y}
lines [[p,p,p,p,p]]; // An array inside lines with 5 points. The last point is
// back to the start
如果添加另一个路径
ctx.moveTo(x,y); // to save me time x and y are points of some coordinate.
ctx.lineTo(x,y);
ctx.lineTo(x,y);
ctx.lineTo(x,y);
// note I did not close path
你必须
moveToPoint(x,y);
addPoint(x,y);
addPoint(x,y);
addPoint(x,y);
与之相匹配的阵列现在看起来像
// p represents a point {x :x,y: y}
lines [[p,p,p,p,p],[p,p,p,p]]; // not second path is not closed and has one less point
,并包含两个路径。
然后,您可以检查使用线功能(在回答的顶部链接)找到最接近的形状,你有你只需要调用该函数,你必须形状
function findclosestPoint(px,py){ // the point px,py
var minDist = Infinity;
var pf = {x:0,y:0}; // the closest point
for(i = 0; i < lines.length; i+=1){
for(j = 0; j < lines[i].length-1; j+=1){
var p = lines[i][j];
var p1 = lines[i][j+1];
// get closet point
var cp = getClosestPointOnLine({x0 : p.x, y0 : p.y, x1 : p1.x, y1 : p1.y},px,py);
// then get the distance.
var x = cp.x - px;
var y = cp.y - py;
x *= x;
y *= y;
var dist = Math.sqrt(x + y);
// is it the closest?
if(dist < minDist){
minDist = dist; // yes remember this distance
pf.x = cp.x;
pf.y = cp.y;
}
}
}
return {dist : minDist, point : pf};
}
的点解决方案。
var closest = findclosestPoint(400,400);
console.log(closest.point) ;// >> {x:?,y:?}
console.log(closest.dist) ;// >> ? in pixels
为了让它适用于弧线,创建一个将弧线分割成更小的线段的功能。贝塞尔曲线和三次曲线相同。相隔2至3个像素的间隔点应该足够多。在StackOverflow中有很多用于查找弧和贝塞尔点的示例。
对于矩形作为一个例子
ctx.rect(x,y,w,h);
创建一个函数来添加定义矩形的线条。
function addRect(x,y,w,h)
addPoint(x,y) // rects start at top left
addPoint(x+w,y)
addPoint(x+w,y+h)
addPoint(x,y+h)
addPoint(x,y)
}
请记住,fillrect和strokeRect以moveTo开头,因此如果需要添加moveToPoint函数调用。
对弧和贝塞尔曲线做同样的操作。
这就是它的全部。
如果你打算有不同的比例和旋转,你将不得不添加这些转换时,你将点添加到线阵列。
如果您希望包含线宽,您将不得不为每条线的边缘创建线条。对贝塞尔来说,这可能会很棘手,但是对于每个在堆栈中的子问题都有解决方案。从基础开始,提炼直至达到目标。
非常感谢! – Mick
形状是否都是多边形 - 由线段组成?当你说“距离”时,你的意思是指形状还是别的什么?如果对两者都是肯定的,你可以测试多边形的每一条线段并[找到距离该点最小的距离](http:// stackoverflow。COM /问题/ 29021887 /拖拽点-沿着矢量与 - 小鼠/ 29023665#29023665)。 – markE
边缘x,y坐标将根据所使用的多边形和画布方法而变化....您可以发布代码示例吗? – KpTheConstructor
据我所知(在所有诚实中有点生锈),因为Canvas使用光栅(像素)绘图,所以一旦你画出一个形状就会被遗忘,当然,你可以比较每个像素的颜色,但这将是昂贵的。最好的方法是跟踪你画到画布上的每一个形状,并与这些形状进行比较,至于数学背后的真正取决于你的使用情况 –