在以下设置中,如何绘制一条穿过两点的“无限”线?
var context = document.getElementById("canvas").getContext("2d");
var point1 = {
x : 120,
y : 100,
};
var point2 = {
x : 250,
y : 300,
};
// mark points in the canvas
context.fillStyle = "red";
context.beginPath();
context.arc(point1.x + 0.5, point1.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
context.beginPath();
context.arc(point2.x + 0.5, point2.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
// draw a line between two points
context.beginPath();
context.moveTo(point1.x, point1.y);
context.lineTo(point2.x, point2.y);
context.stroke();
// draw an "infinite" line that passes through two points
// ??
body {
font-family: sans-serif;
box-sizing: border-box;
background-color: hsl(0, 0%, 90%);
}
canvas {
display: block;
margin: 20px;
background: white;
box-shadow: 0 0 1px rgba(0,0,0,.2),
0 0 3px rgba(0,0,0,.15),
0 1px 2px rgba(0,0,0,.15);
}
<canvas id="canvas" width="400" height="400"></canvas>
我知道我需要计算在同一路径上但不在视图(画布)之外的新坐标,并在它们之间绘制一条线以伪造无限线。
这些新坐标不一定必须位于画布的边缘。我认为这需要额外的计算。所以我在想类似的东西
current position ± canvas diagonal (max distance in canvas)
只是为了确保新坐标始终在画布之外,并跳过多余的计算。
如何计算这些新坐标?
答案 0 :(得分:4)
回溯到代数课,您可以计算出坡度并进行截距,然后使用其在画布边缘上绘制点。如果它们超出了画布的边界,它将创建一条超出边缘的线。
但是请注意,这将不支持水平或垂直线,您必须添加额外的检查以覆盖这些实例。本质上,如果斜率为0,则在两点的y
值处从0到canvas.width绘制一条线,如果未定义,则在{{1 }}两点的值。
x
var context = document.getElementById("canvas").getContext("2d");
var point1 = {
x : 120,
y : 100,
};
var point2 = {
x : 250,
y : 300,
};
var slope = (point2.y - point1.y)/(point2.x - point1.x)
//y = mx + b | b = y - mx
var intercept = point2.y - (slope * point2.x)
function getY(x){ return (slope * x) + intercept; }
function getX(y) { return (y - intercept)/slope; }
// mark points in the canvas
context.fillStyle = "red";
context.beginPath();
context.arc(point1.x + 0.5, point1.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
context.beginPath();
context.arc(point2.x + 0.5, point2.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
// draw a line between two points
context.beginPath();
context.moveTo(getX(0), 0);
context.lineTo(point1.x, point1.y);
context.lineTo(point2.x, point2.y);
context.lineTo(getX(context.canvas.height), context.canvas.height);
context.stroke();
// draw an "infinite" line that passes through two points
// ??
body {
font-family: sans-serif;
box-sizing: border-box;
background-color: hsl(0, 0%, 90%);
}
canvas {
display: block;
margin: 20px;
background: white;
box-shadow: 0 0 1px rgba(0,0,0,.2),
0 0 3px rgba(0,0,0,.15),
0 1px 2px rgba(0,0,0,.15);
}
答案 1 :(得分:0)
您需要找到直线与画布边缘相交的两个点:
var context = document.getElementById("canvas").getContext("2d");
var point1 = {
x : 120,
y : 100,
};
var point2 = {
x : 250,
y : 300,
};
var a = (point2.y - point1.y) / (point2.x - point1.x);
var b = (point1.y * point2.x - point2.y * point1.x) / (point2.x - point1.x);
// mark points in the canvas
context.fillStyle = "red";
context.beginPath();
context.arc(point1.x + 0.5, point1.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
context.beginPath();
context.arc(point2.x + 0.5, point2.y + 0.5, 2, 0, 2 * Math.PI);
context.fill();
// draw a line between two points
//context.beginPath();
//context.moveTo(point1.x, point1.y);
//context.lineTo(point2.x, point2.y);
//context.stroke();
// draw an "infinite" line that passes through two points
// ??
var canvasWidth = context.canvas.width;
var canvasHeight = context.canvas.height;
var leftSideY = b;
var rightSideY = (canvasWidth * a) + b;
var topSideX = (-b) / a;
var bottomSideX = (canvasHeight - b) / a;
// vertical line
if ([Infinity, -Infinity].includes(a)) {
topSideX = bottomSideX = point1.x;
}
// same points
if (a !== a) {
throw new Error("point1 and point2 are the same")
}
const edgePoints = [
{x: 0, y: leftSideY},
{x: canvasWidth, y: rightSideY},
{x: topSideX, y: 0},
{x: bottomSideX, y: canvasHeight}
].filter(({x, y}) => x >= 0 && x <= canvasWidth && y >= 0 && y <= canvasHeight);
context.beginPath();
context.moveTo(edgePoints[0].x , edgePoints[0].y || 0);
context.lineTo(edgePoints[1].x || point2.x, edgePoints[1].y || canvasHeight);
context.stroke();
body {
font-family: sans-serif;
box-sizing: border-box;
background-color: hsl(0, 0%, 90%);
}
canvas {
display: block;
margin: 20px;
background: white;
box-shadow: 0 0 1px rgba(0,0,0,.2),
0 0 3px rgba(0,0,0,.15),
0 1px 2px rgba(0,0,0,.15);
}
<canvas id="canvas" width="400" height="400"></canvas>