如何简化判断点是否属于指定区域的条件表达式?
Simplify Point-in-Area Check Conditions in C
Hey there! Let's clean up that clunky condition check while making sure it behaves exactly like your original working code. First, let's recap your original code (with a tiny fix for the printf calls—they had missing format specifiers that might have caused odd behavior):
float x, y; int a = 2, b = 1, r = 3; printf("x = "); scanf("%f", &x); printf("y = "); scanf("%f", &y); if ( ((pow((x-a), 2) + pow((y-b), 2) <= pow(r,2)) && ((pow((x-a), 2) + pow((y-b),2) >= 1)) && (x <= 2) && (x >= -3) && (y >= -1) && (y <= 4)) || (fabs(x) <= 1 && fabs(y) <=1) || (y == x+2 && y >= -1 && x >= -3)) { printf("Belongs to the area"); } else { printf("Doesn't belong to the area"); }
Key Simplifications We Can Make
The biggest pain points in your original code are repeated calculations and messy condition grouping. Here's how to fix that without breaking functionality:
- Cache repeated calculations: You compute
(x-a)² + (y-b)²three times—we can calculate this once and store it in a variable to save computation and clean up the code. - Group logical conditions clearly: Break each distinct area check into its own named block, so anyone reading the code can instantly see which condition maps to which region.
- Fix floating-point equality: Directly checking
y == x+2can fail due to floating-point precision errors—we'll use a small epsilon value to handle this safely. - Replace
powfor simple squares: Using(x-a)*(x-a)instead ofpow(x-a, 2)is faster and more readable for basic squaring operations.
Simplified Working Code
#include <stdio.h> #include <math.h> int main() { float x, y; const int a = 2, b = 1, r = 3; printf("Enter x: "); scanf("%f", &x); printf("Enter y: "); scanf("%f", &y); // Calculate squared distance from (x,y) to center (a,b) once float dist_sq = (x - a) * (x - a) + (y - b) * (y - b); const float r_sq = r * r; // Precompute squared radius to avoid repeat math // Break each area check into a readable, named variable int in_ring = (dist_sq <= r_sq) && (dist_sq >= 1) && (x >= -3) && (x <= 2) && (y >= -1) && (y <= 4); int in_small_square = (fabs(x) <= 1) && (fabs(y) <= 1); // Use epsilon for float equality check to avoid precision issues int on_line_segment = (fabs(y - (x + 2)) < 1e-6) && (y >= -1) && (x >= -3); if (in_ring || in_small_square || on_line_segment) { printf("Belongs to the area\n"); } else { printf("Doesn't belong to the area\n"); } return 0; }
Quick Notes on the Changes
- Named variables:
in_ring,in_small_square, andon_line_segmentturn a giant, unreadableifcondition into something that's instantly understandable. - Floating-point safety: The
1e-6epsilon accounts for tiny precision errors in float calculations, which would have made your originaly == x+2check fail unexpectedly in some cases. - Efficiency: By caching repeated calculations, we avoid redundant math operations, making the code slightly faster while keeping it functionally identical to your original.
内容的提问来源于stack exchange,提问作者Darya Balu
相关产品推荐
相关产品推荐

