如何在Processing中统一绘制椭圆扇形区域?
Hey there! I see the issue with your current approach to drawing the white ellipse sector—using repeated lines from the center to offset points creates uneven "width" because arc lengths on an ellipse vary with angle, even for the same parameter increment. Let's replace that with a proper angle-based sector drawing method that stays consistent no matter where it's placed.
Step 1: Refactor How You Store Sector Data
Instead of storing a single random point, let's track a fixed angle range for the sector. Add these variables at the top of your code (replacing the old region variable):
var sectorStartAngle; const SECTOR_SPAN = 30; // Fixed angle width for the sector (adjust this to make it wider/narrower)
Step 2: Rewrite the drawRegion Function
Use Processing's shape-drawing tools to create a clean, consistent sector. This will draw a closed shape from the center, around the ellipse arc of your chosen angle range, and back to the center:
function drawRegion(centerX, centerY, radiusX, radiusY) { if (first) { first = false; // Pick a random starting angle for the sector sectorStartAngle = Math.random() * 360; } fill("#ffffff"); stroke("white"); // Keep this if you want a border, remove if not beginShape(); // Start at the center of the ellipse vertex(centerX, centerY); // Draw points along the ellipse arc for the sector's angle range const angleStep = 1; // Smaller = smoother arc, larger = faster drawing for (let angle = sectorStartAngle; angle <= sectorStartAngle + SECTOR_SPAN; angle += angleStep) { const radians = angle * Math.PI / 180; const x = centerX + radiusX * Math.cos(radians); const y = centerY + radiusY * Math.sin(radians); vertex(x, y); } // Close the shape by returning to the center vertex(centerX, centerY); endShape(); }
Step 3: Simplify Collision Detection
Instead of checking if your red line's endpoint matches a drawn line, just check if the line's angle falls within the sector's angle range. Update your keyPressed function like this:
function keyPressed() { if (key === " ") { diff *= -1; } // Normalize the current angle to 0-360 degrees let currentAngle = angle % 360; if (currentAngle < 0) currentAngle += 360; // Calculate the sector's end angle (also normalized) let sectorEndAngle = (sectorStartAngle + SECTOR_SPAN) % 360; let isHit = false; // Handle the wrap-around case (e.g., sector starts at 350° and ends at 20°) if (sectorStartAngle <= sectorEndAngle) { isHit = currentAngle >= sectorStartAngle && currentAngle <= sectorEndAngle; } else { isHit = currentAngle >= sectorStartAngle || currentAngle <= sectorEndAngle; } // Update score and difficulty if (isHit) { score++; first = true; // Spawn a new sector // Increase speed gradually if (diff > 0 && diff < 3) diff += 0.1; else if (diff > -3) diff -= 0.1; } else { score--; } }
Bonus Tweaks
- You can keep your
ellipseGetPointfunction—it still works perfectly for calculating the red line's endpoint. - Adjust
SECTOR_SPANto make the sector wider (easier game) or narrower (harder game).
This approach ensures your sector has a consistent size every time, and the collision detection is more reliable than checking for matching pixel positions.
内容的提问来源于stack exchange,提问作者Norhther

