求绘制垂直、水平及45度直线的简洁高效算法
Nice catch on the DRY violation here—your original approach works, but repeating logic across those conditional blocks is definitely a maintainability red flag. Let's refactor this into a cleaner, more concise version that handles vertical, horizontal, and 45-degree lines without redundant code, while ignoring all other line types.
Key Insight
All three supported line types share a core pattern: each step moves exactly one pixel along the x-axis, y-axis, or both. Instead of writing separate logic for each case, we can compute direction steps once and use a single drawing loop that works for all valid lines.
Refactored Code
void line(int x0, int y0, int x1, int y1) { int dx = x1 - x0; int dy = y1 - y0; // Check if line is vertical, horizontal, or 45-degree if (dx == 0 || dy == 0 || abs(dx) == abs(dy)) { // Calculate direction steps (1 for positive, -1 for negative, 0 for no movement) int step_x = (dx > 0) ? 1 : (dx < 0) ? -1 : 0; int step_y = (dy > 0) ? 1 : (dy < 0) ? -1 : 0; // Number of steps needed to traverse the line (max of absolute dx/dy) int steps = max(abs(dx), abs(dy)); int current_x = x0; int current_y = y0; for (int i = 0; i <= steps; i++) { // Replace this with your actual pixel-drawing logic draw_pixel(current_x, current_y); current_x += step_x; current_y += step_y; } } // For non-supported lines, we do nothing (function exits silently) }
Why This Works Better
- DRY Compliance: No repeated drawing logic—all three line types use the same loop. If you ever need to modify how pixels are drawn (e.g., add anti-aliasing), you only change it once.
- Simplified Conditionals: A single check replaces your nested if/else chain, making the code easier to read and debug.
- Flexible Direction Handling: The
step_xandstep_yvariables automatically handle positive/negative directions, so the loop works regardless of whether you're drawing left-to-right, top-to-bottom, etc. - Explicit Ignoration: Non-supported lines are ignored by design, which aligns perfectly with your requirement.
Optional Optimization (If Needed)
If you're working in a performance-critical context and want to optimize vertical/horizontal lines (since they don't need to update both axes each step), you can add minor branching inside the loop—but this comes at the cost of a tiny bit of DRY. For most use cases, the above version is the sweet spot between simplicity and performance.
内容的提问来源于stack exchange,提问作者masi

