我尝试过一些三角函数并使用极坐标到笛卡尔坐标,但最终对如何在 JS 中实现效果有点迷失。目前我一直在使用 p5.js,但对其他选项持开放态度。
本质上,我想在屏幕上有一个圆圈,并且有一个不可见的光在圆圈上投射出阴影。最终我希望“光”和圆圈位置可以移动,但现在我很难创建阴影的形状。
我已经可以从光标的一点创建圆的切线,但不能在其之外“投射阴影”。
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background("#9B009D");
const circleCenterX = width / 2;
const circleCenterY = height / 2;
const circleRadius = 200;
if (mouseX !== 0 || mouseY !== 0) {
drawTangentLines(mouseX, mouseY, circleCenterX, circleCenterY, circleRadius);
fill("#FF7000");
noStroke;
ellipse(circleCenterX, circleCenterY, circleRadius * 2);
}
}
function drawTangentLines(pointX, pointY, centerX, centerY, radius) {
const dx = pointX - centerX;
const dy = pointY - centerY;
const directDistance = sqrt(dx * dx + dy * dy);
if (directDistance < radius) {
// If the point is inside the circle, do not draw tangent lines.
return;
}
// Determine angles for the tangent points
const angleToCenter = atan2(dy, dx);
const angleFromTangent = acos(radius / directDistance); // Proper angle to tangent points
// Calculate tangents
const angle1 = angleToCenter + angleFromTangent;
const angle2 = angleToCenter - angleFromTangent;
// Calculate tangent points on the circle
const tanPoint1X = centerX + radius * cos(angle1);
const tanPoint1Y = centerY + radius * sin(angle1);
const tanPoint2X = centerX + radius * cos(angle2);
const tanPoint2Y = centerY + radius * sin(angle2);
// Draw lines from external point to tangent points
line(pointX, pointY, tanPoint1X, tanPoint1Y);
line(pointX, pointY, tanPoint2X, tanPoint2Y);
noStroke();
fill("white");
beginShape();
vertex(pointX, pointY);
vertex(tanPoint1X, tanPoint1Y);
vertex(tanPoint2X, tanPoint2Y);
endShape(CLOSE);
}
function mouseMoved() {
redraw();
}
最终到达那里,这并不微妙,只是通过一些简单的乘法将点扩展到画布之外并填充该区域!
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background("#9B009D");
const circleCenterX = width / 2;
const circleCenterY = height / 2;
const circleRadius = 200;
if (mouseX !== 0 || mouseY !== 0) {
drawTangentLines(mouseX, mouseY, circleCenterX, circleCenterY, circleRadius);
fill("#FF7000");
//noStroke;
ellipse(circleCenterX, circleCenterY, circleRadius * 2);
}
}
function drawTangentLines(pointX, pointY, centerX, centerY, radius) {
const dx = pointX - centerX;
const dy = pointY - centerY;
const directDistance = sqrt(dx * dx + dy * dy);
if (directDistance < radius) {
// If the point is inside the circle, do not draw tangent lines.
return;
}
// Determine angles for the tangent points
const angleToCenter = atan2(dy, dx);
const angleFromTangent = acos(radius / directDistance); // Proper angle to tangent points
// Calculate tangents
const angle1 = angleToCenter + angleFromTangent;
const angle2 = angleToCenter - angleFromTangent;
// Calculate tangent points on the circle
const tanPoint1X = centerX + radius * cos(angle1);
const tanPoint1Y = centerY + radius * sin(angle1);
const tanPoint2X = centerX + radius * cos(angle2);
const tanPoint2Y = centerY + radius * sin(angle2);
const diff1X = tanPoint1X - pointX;
const diff1Y = tanPoint1Y - pointY;
const diff2X = tanPoint2X - pointX;
const diff2Y = tanPoint2Y - pointY;
// Draw lines from external point to tangent points
line(pointX, pointY, tanPoint1X, tanPoint1Y);
line(pointX, pointY, tanPoint2X, tanPoint2Y);
line(tanPoint1X, tanPoint1Y, tanPoint1X+(1000* diff1X), tanPoint1Y+(1000*diff1Y));
line(tanPoint2X, tanPoint2Y, tanPoint2X+(1000* diff2X), tanPoint2Y+(1000*diff2Y));
//noStroke();
fill("white");
beginShape();
vertex(tanPoint1X, tanPoint1Y);
vertex(tanPoint1X+(1000* diff1X),tanPoint1Y+(1000*diff1Y));
vertex(tanPoint2X+(1000* diff2X),tanPoint2Y+(1000*diff2Y));
vertex(tanPoint2X, tanPoint2Y);
endShape(CLOSE);
}
function mouseMoved() {
redraw();
}