Changeset 10254 for trunk/psLib/src/math/psEllipse.c
- Timestamp:
- Nov 28, 2006, 4:33:08 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psEllipse.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psEllipse.c
r9774 r10254 1 1 #include <stdio.h> 2 #include <assert.h> 2 3 #include "psConstants.h" 3 4 #include "psEllipse.h" 4 5 5 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments) 6 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 7 psEllipseMoments psEllipseAxesToMoments(psEllipseAxes axes) 8 { 9 psEllipseMoments moments; 10 11 double f1 = PS_SQR(axes.major) + PS_SQR(axes.minor); 12 double f2 = PS_SQR(axes.major) - PS_SQR(axes.minor); 13 14 moments.x2 = +0.5*f1 + 0.5*f2*cos(2*axes.theta); 15 moments.y2 = +0.5*f1 - 0.5*f2*cos(2*axes.theta); 16 moments.xy = -0.5*f2*sin(2*axes.theta); 17 18 assert (isfinite(moments.x2)); 19 assert (isfinite(moments.y2)); 20 assert (isfinite(moments.xy)); 21 22 return moments; 23 } 24 25 // ellipse rotation (x2, y2, xy) -> (major, minor, theta) 26 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments, double maxAR) 6 27 { 7 28 psEllipseAxes axes; 8 29 9 double f = sqrt (0.25*PS_SQR(moments.x2 - moments.y2) + PS_SQR(moments.xy)); 10 if (f > (moments.x2 + moments.y2) / 2.0) { 11 f = 0.98*(moments.x2 + moments.y2) / 2.0; 30 double g1 = moments.x2 + moments.y2; 31 double g2 = moments.x2 - moments.y2; 32 double g3 = sqrt(PS_SQR(g2) + 4*PS_SQR(moments.xy)); 33 34 axes.major = sqrt (0.5*(g1 + g3)); 35 axes.theta = 0.5 * atan2 (-2.0*moments.xy, g2); // theta in radians 36 37 // long, thin objects are likely to have a poorly measured minor axis 38 // the angle and major axis are likely to be ok. 39 // restrict the axis ratio 40 double rAR2 = (g1 - g3) / (g1 + g3); 41 if (rAR2 < 1.0/PS_SQR(maxAR)) { 42 axes.minor = axes.major / maxAR; 43 } else { 44 axes.minor = sqrt (0.5*(g1 - g3)); 12 45 } 13 46 14 axes.major = sqrt (0.5*(moments.x2 + moments.y2) + f); 15 axes.minor = sqrt (0.5*(moments.x2 + moments.y2) - f); 16 axes.theta = atan2 (2*moments.xy, moments.x2 - moments.y2) / 2; 17 // theta in radians 47 assert (isfinite(axes.major)); 48 assert (isfinite(axes.minor)); 49 assert (isfinite(axes.theta)); 18 50 19 51 return axes; … … 25 57 psEllipseShape shape; 26 58 27 double f1 = 1.0 / PS_SQR(axes.m ajor) + 1.0 / PS_SQR(axes.minor);28 double f2 = 1.0 / PS_SQR(axes.m ajor) - 1.0 / PS_SQR(axes.minor);59 double f1 = 1.0 / PS_SQR(axes.minor) + 1.0 / PS_SQR(axes.major); 60 double f2 = 1.0 / PS_SQR(axes.minor) - 1.0 / PS_SQR(axes.major); 29 61 30 double sxr = 0.5*f1 +0.5*f2*cos(2*axes.theta);31 double syr = 0.5*f1 -0.5*f2*cos(2*axes.theta);62 double sxr = 0.5*f1 - 0.5*f2*cos(2*axes.theta); 63 double syr = 0.5*f1 + 0.5*f2*cos(2*axes.theta); 32 64 33 shape.sx = 1.0 / sqrt(sxr); 34 shape.sy = 1.0 / sqrt(syr); 35 shape.sxy = 0.5*f2*sin(2*axes.theta); 65 shape.sx = +1.0 / sqrt(sxr); 66 shape.sy = +1.0 / sqrt(syr); 67 shape.sxy = -0.5*f2*sin(2*axes.theta); 68 69 assert (isfinite(shape.sx)); 70 assert (isfinite(shape.sy)); 71 assert (isfinite(shape.sxy)); 36 72 37 73 return shape; … … 39 75 40 76 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta) 41 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape )77 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape, double maxAR) 42 78 { 43 79 psEllipseAxes axes; 44 80 45 double f1 = 1.0 / PS_SQR(shape.s x) + 1.0 / PS_SQR(shape.sy);46 double f2 = 1.0 / PS_SQR(shape.s x) - 1.0 / PS_SQR(shape.sy);81 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx); 82 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx); 47 83 double f3 = sqrt(PS_SQR(f2) + 4*PS_SQR(shape.sxy)); 48 84 49 axes.theta = 0.5 * atan2 (2*shape.sxy, f2);50 axes.major = sqrt (2.0 / (f1 - f3));51 85 axes.minor = sqrt (2.0 / (f1 + f3)); 86 axes.theta = 0.5 * atan2 (-2.0*shape.sxy, f2); 87 88 // long, thin objects are likely to have a poorly measured major axis 89 // the angle and minor axis are likely to be ok. 90 // restrict the axis ratio 91 double rAR2 = (f1 - f3) / (f1 + f3); 92 if (rAR2 < 1.0/PS_SQR(maxAR)) { 93 axes.major = axes.minor * maxAR; 94 } else { 95 axes.major = sqrt (2.0 / (f1 - f3)); 96 } 97 98 assert (isfinite(axes.theta)); 99 assert (isfinite(axes.major)); 100 assert (isfinite(axes.minor)); 52 101 53 102 return axes; … … 57 106 // force the axis ratio to be less than 10 58 107 // double r1 = 0.5*0.95*sqrt (PS_SQR(f1) - PS_SQR(f2)); 108 109 // double f = sqrt (0.25*PS_SQR(moments.x2 - moments.y2) + PS_SQR(moments.xy)); 110 // if (f > (moments.x2 + moments.y2) / 2.0) { 111 // f = 0.98*(moments.x2 + moments.y2) / 2.0;
Note:
See TracChangeset
for help on using the changeset viewer.
