Changeset 36375 for trunk/psLib/src/math/psEllipse.c
- Timestamp:
- Dec 10, 2013, 2:55:11 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psLib/src/math/psEllipse.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
trunk/psLib/src/math/psEllipse.c
r35555 r36375 12 12 // f = exp(-z) where z describes the elliptical contour at any flux level: 13 13 14 // NOTE: major, minor are the 1-sigma lengths in the major,minor directions assuming the 15 // moments represent a Gaussian profile 16 14 17 // sigma shape: z = 0.5((x/sx)^2 + (y/sy)^2 + sxy*x*y) 15 18 // sigma axes : z = 0.5((x/sa)^2 + (y/sb)^2), x,y rotated by theta … … 17 20 // polarization : e0, e1, e2 18 21 19 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 22 // ellipse rotation (major, minor, theta) -> (Mxx, Mxy, Myy) 23 psEllipseMoments psEllipseAxesToMoments(psEllipseAxes axes) 24 { 25 psEllipseMoments moments; 26 27 double f1 = PS_SQR(axes.major) + PS_SQR(axes.minor); 28 double f2 = PS_SQR(axes.major) - PS_SQR(axes.minor); 29 30 moments.x2 = +0.5*f1 + 0.5*f2*cos(2*axes.theta); 31 moments.y2 = +0.5*f1 - 0.5*f2*cos(2*axes.theta); 32 moments.xy = +0.5*f2*sin(2*axes.theta); 33 34 assert (isfinite(moments.x2)); 35 assert (isfinite(moments.y2)); 36 assert (isfinite(moments.xy)); 37 38 return moments; 39 } 40 41 // ellipse rotation (Mxx, Mxy, Myy) -> (major, minor, theta). 42 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments, double maxAR) 43 { 44 psEllipseAxes axes; 45 psEllipseAxes badValue = {NAN, NAN, NAN}; 46 47 if (!isfinite(moments.x2)) return badValue; 48 if (!isfinite(moments.y2)) return badValue; 49 if (!isfinite(moments.xy)) return badValue; 50 51 if (moments.x2 < 0) return badValue; 52 if (moments.y2 < 0) return badValue; 53 54 double g1 = moments.x2 + moments.y2; 55 double g2 = moments.x2 - moments.y2; 56 double g3 = sqrt(PS_SQR(g2) + 4*PS_SQR(moments.xy)); 57 58 axes.major = sqrt (0.5*(g1 + g3)); 59 axes.theta = +0.5 * atan2 (+2.0*moments.xy, g2); // theta in radians 60 61 // long, thin objects are likely to have a poorly measured minor axis 62 // the angle and major axis are likely to be ok. 63 // restrict the axis ratio 64 double rAR2 = (g1 - g3) / (g1 + g3); 65 if (rAR2 < 1.0/PS_SQR(maxAR)) { 66 axes.minor = axes.major / maxAR; 67 } else { 68 axes.minor = sqrt (0.5*(g1 - g3)); 69 } 70 71 assert (isfinite(axes.major)); 72 assert (isfinite(axes.minor)); 73 assert (isfinite(axes.theta)); 74 75 return axes; 76 } 77 78 // ellipse rotation (major, minor, theta) -> (sx, sy, sxy) 79 // theta is postive rotation of major axis away from x-axis 80 psEllipseShape psEllipseAxesToShape(psEllipseAxes axes) 81 { 82 psEllipseShape shape; 83 psEllipseShape badValue = {NAN, NAN, NAN}; 84 85 if (!isfinite(axes.minor)) return badValue; 86 if (!isfinite(axes.major)) return badValue; 87 if (!isfinite(axes.theta)) return badValue; 88 89 if (axes.minor <= 0) return badValue; 90 if (axes.major <= 0) return badValue; 91 92 double f1 = 1.0 / PS_SQR(axes.minor) + 1.0 / PS_SQR(axes.major); 93 double f2 = 1.0 / PS_SQR(axes.minor) - 1.0 / PS_SQR(axes.major); 94 95 double sxr = 0.5*f1 - 0.5*f2*cos(2*axes.theta); 96 double syr = 0.5*f1 + 0.5*f2*cos(2*axes.theta); 97 98 // sxr, syr cannot be < 0 (f1 >= f2) 99 100 shape.sx = +1.0 / sqrt(sxr); 101 shape.sy = +1.0 / sqrt(syr); 102 shape.sxy = -0.5*f2*sin(2*axes.theta); 103 104 assert (isfinite(shape.sx)); 105 assert (isfinite(shape.sy)); 106 assert (isfinite(shape.sxy)); 107 108 return shape; 109 } 110 111 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta) 112 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape, double maxAR) 113 { 114 psEllipseAxes axes; 115 116 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx); 117 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx); 118 double f3 = sqrt(PS_SQR(f2) + 4*PS_SQR(shape.sxy)); 119 120 axes.minor = sqrt (2.0 / (f1 + f3)); 121 axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2); 122 123 // long, thin objects are likely to have a poorly measured major axis 124 // the angle and minor axis are likely to be ok. 125 // restrict the axis ratio 126 double rAR2 = (f1 - f3) / (f1 + f3); 127 if (rAR2 < 1.0/PS_SQR(maxAR)) { 128 axes.major = axes.minor * maxAR; 129 } else { 130 axes.major = sqrt (2.0 / (f1 - f3)); 131 } 132 133 assert (isfinite(axes.theta)); 134 assert (isfinite(axes.major)); 135 assert (isfinite(axes.minor)); 136 137 return axes; 138 } 139 140 // ellipse rotation (major, minor, theta) -> (e0, e1, e2) 20 141 psEllipsePol psEllipseAxesToPol(psEllipseAxes axes) 21 142 { … … 35 156 } 36 157 37 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 38 psEllipsePol psEllipseShapeToPol(psEllipseShape shape) 39 { 40 psEllipsePol pol; 41 42 double r = 1.0 / (1.0 - PS_SQR(shape.sx)*PS_SQR(shape.sy)*PS_SQR(shape.sxy)); 43 44 pol.e0 = r*(PS_SQR(shape.sx) + PS_SQR(shape.sy)); 45 pol.e1 = r*(PS_SQR(shape.sx) - PS_SQR(shape.sy)); 46 // XXX I do not understand this negative sign 47 pol.e2 = -r*(2.0*PS_SQR(shape.sx)*PS_SQR(shape.sy)*shape.sxy); 48 49 assert (isfinite(pol.e0)); 50 assert (isfinite(pol.e1)); 51 assert (isfinite(pol.e2)); 52 53 return pol; 54 } 55 56 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 57 // XXXX handle case where e0 < LIMIT 158 // ellipse rotation (e0, e1, e2) -> (major, minor, theta) 58 159 psEllipseAxes psEllipsePolToAxes(const psEllipsePol pol, 59 160 const float minMinorAxis) … … 96 197 } 97 198 98 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 99 psEllipseMoments psEllipseAxesToMoments(psEllipseAxes axes) 100 { 101 psEllipseMoments moments; 102 103 double f1 = PS_SQR(axes.major) + PS_SQR(axes.minor); 104 double f2 = PS_SQR(axes.major) - PS_SQR(axes.minor); 105 106 moments.x2 = +0.5*f1 + 0.5*f2*cos(2*axes.theta); 107 moments.y2 = +0.5*f1 - 0.5*f2*cos(2*axes.theta); 108 moments.xy = +0.5*f2*sin(2*axes.theta); 109 110 assert (isfinite(moments.x2)); 111 assert (isfinite(moments.y2)); 112 assert (isfinite(moments.xy)); 113 114 return moments; 115 } 116 117 // ellipse rotation (x2, y2, xy) -> (major, minor, theta). NOTE: major, minor are the 118 // 1-sigma lengths in the major,minor directions assuming the moments represent a Gaussian 119 // profile 120 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments, double maxAR) 121 { 122 psEllipseAxes axes; 123 psEllipseAxes badValue = {NAN, NAN, NAN}; 124 125 if (!isfinite(moments.x2)) return badValue; 126 if (!isfinite(moments.y2)) return badValue; 127 if (!isfinite(moments.xy)) return badValue; 128 129 if (moments.x2 < 0) return badValue; 130 if (moments.y2 < 0) return badValue; 131 132 double g1 = moments.x2 + moments.y2; 133 double g2 = moments.x2 - moments.y2; 134 double g3 = sqrt(PS_SQR(g2) + 4*PS_SQR(moments.xy)); 135 136 axes.major = sqrt (0.5*(g1 + g3)); 137 axes.theta = +0.5 * atan2 (+2.0*moments.xy, g2); // theta in radians 138 139 // long, thin objects are likely to have a poorly measured minor axis 140 // the angle and major axis are likely to be ok. 141 // restrict the axis ratio 142 double rAR2 = (g1 - g3) / (g1 + g3); 143 if (rAR2 < 1.0/PS_SQR(maxAR)) { 144 axes.minor = axes.major / maxAR; 145 } else { 146 axes.minor = sqrt (0.5*(g1 - g3)); 147 } 148 149 assert (isfinite(axes.major)); 150 assert (isfinite(axes.minor)); 151 assert (isfinite(axes.theta)); 152 153 return axes; 154 } 155 156 // ellipse rotation (major, minor, theta) -> (sx, sy, sxy) 157 // theta is postive rotation of major axis away from x-axis 158 psEllipseShape psEllipseAxesToShape(psEllipseAxes axes) 199 // ellipse rotation (sx, sy, sxy) -> (e0, e1, e2) 200 psEllipsePol psEllipseShapeToPol(psEllipseShape shape) 201 { 202 psEllipsePol pol; 203 204 double r = 1.0 / (1.0 - PS_SQR(shape.sx)*PS_SQR(shape.sy)*PS_SQR(shape.sxy)); 205 206 pol.e0 = r*(PS_SQR(shape.sx) + PS_SQR(shape.sy)); 207 pol.e1 = r*(PS_SQR(shape.sx) - PS_SQR(shape.sy)); 208 // XXX I do not understand this negative sign 209 pol.e2 = -r*(2.0*PS_SQR(shape.sx)*PS_SQR(shape.sy)*shape.sxy); 210 211 assert (isfinite(pol.e0)); 212 assert (isfinite(pol.e1)); 213 assert (isfinite(pol.e2)); 214 215 return pol; 216 } 217 218 // ellipse rotation (e0, e1, e2) -> (sx, sy, sxy) 219 psEllipseShape psEllipsePolToShape(psEllipsePol pol) 159 220 { 160 221 psEllipseShape shape; 161 psEllipseShape badValue = {NAN, NAN, NAN}; 162 163 if (!isfinite(axes.minor)) return badValue; 164 if (!isfinite(axes.major)) return badValue; 165 if (!isfinite(axes.theta)) return badValue; 166 167 if (axes.minor <= 0) return badValue; 168 if (axes.major <= 0) return badValue; 169 170 double f1 = 1.0 / PS_SQR(axes.minor) + 1.0 / PS_SQR(axes.major); 171 double f2 = 1.0 / PS_SQR(axes.minor) - 1.0 / PS_SQR(axes.major); 172 173 double sxr = 0.5*f1 - 0.5*f2*cos(2*axes.theta); 174 double syr = 0.5*f1 + 0.5*f2*cos(2*axes.theta); 175 176 // sxr, syr cannot be < 0 (f1 >= f2) 177 178 shape.sx = +1.0 / sqrt(sxr); 179 shape.sy = +1.0 / sqrt(syr); 180 shape.sxy = -0.5*f2*sin(2*axes.theta); 222 223 double q = sqrt (PS_SQR(pol.e1) + PS_SQR(pol.e2)); 224 double p = PS_SQR(pol.e0) + PS_SQR(q) - 2.0*q*pol.e0; 225 226 // double f1 = 4*pol.e0 / p; 227 // double f2 = 4*q / p; 228 229 double sxr = 2.0*(pol.e0 - pol.e1) / p; 230 double syr = 2.0*(pol.e0 + pol.e1) / p; 231 232 shape.sx = sqrt(1.0 / sxr); 233 shape.sy = sqrt(1.0 / syr); 234 235 shape.sxy = -2.0 * pol.e2 / p; 181 236 182 237 assert (isfinite(shape.sx)); … … 187 242 } 188 243 189 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta)190 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape, double maxAR)191 {192 psEllipseAxes axes;193 194 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx);195 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx);196 double f3 = sqrt(PS_SQR(f2) + 4*PS_SQR(shape.sxy));197 198 axes.minor = sqrt (2.0 / (f1 + f3));199 axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2);200 201 // long, thin objects are likely to have a poorly measured major axis202 // the angle and minor axis are likely to be ok.203 // restrict the axis ratio204 double rAR2 = (f1 - f3) / (f1 + f3);205 if (rAR2 < 1.0/PS_SQR(maxAR)) {206 axes.major = axes.minor * maxAR;207 } else {208 axes.major = sqrt (2.0 / (f1 - f3));209 }210 211 assert (isfinite(axes.theta));212 assert (isfinite(axes.major));213 assert (isfinite(axes.minor));214 215 return axes;216 }217 218 244 // XXX keep this construction? 219 245 // force the axis ratio to be less than 10
Note:
See TracChangeset
for help on using the changeset viewer.
