convert three-point circle to two-point rectangular bounds */
| 941 | |
| 942 | /* convert three-point circle to two-point rectangular bounds */ |
| 943 | static int msOCIConvertCircle( pointObj *pt ) |
| 944 | { |
| 945 | pointObj ptaux; |
| 946 | double dXa, dXb; |
| 947 | double ma, mb; |
| 948 | double cx, cy, r; |
| 949 | int success; |
| 950 | |
| 951 | dXa = pt[1].x - pt[0].x; |
| 952 | success = (fabs( dXa ) > 1e-8); |
| 953 | if (!success) |
| 954 | { /* switch points 1 & 2 */ |
| 955 | ptaux = pt[1]; |
| 956 | pt[1] = pt[2]; |
| 957 | pt[2] = ptaux; |
| 958 | dXa = pt[1].x - pt[0].x; |
| 959 | success = (fabs( dXa ) > 1e-8); |
| 960 | } |
| 961 | if (success) |
| 962 | { |
| 963 | dXb = pt[2].x - pt[1].x; |
| 964 | success = (fabs( dXb ) > 1e-8); |
| 965 | if (!success) |
| 966 | { /* insert point 2 before point 0 */ |
| 967 | ptaux = pt[2]; |
| 968 | pt[2] = pt[1]; |
| 969 | pt[1] = pt[0]; |
| 970 | pt[0] = ptaux; |
| 971 | dXb = dXa; /* segment A has become B */ |
| 972 | dXa = pt[1].x - pt[0].x; /* recalculate new segment A */ |
| 973 | success = (fabs( dXa ) > 1e-8); |
| 974 | } |
| 975 | } |
| 976 | if (success) |
| 977 | { |
| 978 | ma = (pt[1].y - pt[0].y)/dXa; |
| 979 | mb = (pt[2].y - pt[1].y)/dXb; |
| 980 | success = (fabs( mb - ma ) > 1e-8); |
| 981 | } |
| 982 | if (!success) |
| 983 | return 0; |
| 984 | |
| 985 | /* calculate center and radius */ |
| 986 | cx = (ma*mb*(pt[0].y - pt[2].y) + mb*(pt[0].x + pt[1].x) - ma*(pt[1].x + pt[2].x))/(2*(mb - ma)); |
| 987 | cy = (fabs( ma ) > 1e-8) |
| 988 | ? ((pt[0].y + pt[1].y)/2 - (cx - (pt[0].x + pt[1].x)/2)/ma) |
| 989 | : ((pt[1].y + pt[2].y)/2 - (cx - (pt[1].x + pt[2].x)/2)/mb); |
| 990 | |
| 991 | r = sqrt( pow( pt[0].x - cx, 2 ) + pow( pt[0].y - cy, 2 ) ); |
| 992 | |
| 993 | /* update pt buffer with rectangular bounds */ |
| 994 | pt[0].x = cx - r; |
| 995 | pt[0].y = cy - r; |
| 996 | pt[1].x = cx + r; |
| 997 | pt[1].y = cy + r; |
| 998 | |
| 999 | return 1; |
| 1000 | } |