チェンジセット 91

差分発生行の前後
無視リスト:
コミット日時:
2007/10/15 09:02:14 (6 年前)
コミッタ:
nitoyon
ログメッセージ:

高速化した
mx 名前空間を使わないようにした

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • nitoyon/as3/src/com/nitoyon/potras/Curve.as

    r85 r91  
    88{ 
    99import flash.geom.Point; 
    10 import mx.utils.StringUtil; 
    1110 
    1211public class Curve 
     
    3938        public function toString():String 
    4039        { 
    41                 return StringUtil.substitute( 
    42                           "alpha0: {0}\n" 
    43                         + "alpha:  {1}\n" 
    44                         + "beta:   {2}\n" 
    45                         + "corner: {3}\n" 
    46                         + "bezier: {4},{5}{6}", 
    47                         alpha0, alpha, beta, tag == ProcessPath.POTRACE_CORNER, c[0], c[1], c[2]); 
     40                return "alpha0: " + alpha0 + "\n" 
     41                     + "alpha:  " + alpha + "\n" 
     42                     + "beta:   " + beta + "\n" 
     43                     + "corner: " + (tag == ProcessPath.POTRACE_CORNER) + "\n" 
     44                     + "bezier: " + c[0] + "," + c[1] + "," + c[2]; 
    4845        } 
    4946} 
  • nitoyon/as3/src/com/nitoyon/potras/PathList.as

    r85 r91  
    3232                        var param:Object = {turdSize : 3}; 
    3333 
    34                         var point:Point; 
    35                         while(point = findNext(bmdCopy, y)) 
     34                        // XOR 
     35                        var filter:ColorMatrixFilter = new ColorMatrixFilter([ 
     36                                -1, 0, 0, 0, 255,  
     37                                -1, 0, 0, 0, 255,  
     38                                -1, 0, 0, 0, 255, 
     39                                 0, 0, 0, 1, 0 
     40                        ]); 
     41 
     42                        var point:Point = new Point(); 
     43                        while(findNext(bmdCopy, point)) 
    3644                        { 
    3745                                // calculate the sign by looking at the original 
     
    4250                                if(!p) 
    4351                                { 
    44                                         bitmapData.dispose()
    45                                         return null
     52                                        pathList = null
     53                                        break
    4654                                } 
    4755 
    4856                                // update buffered image 
    49                                 xorPath(bmdCopy, p); 
     57                                xorPath(bmdCopy, p, filter); 
    5058 
    5159                                // if it's a turd, eliminate it, else append it to the list 
     
    6775                 * <p>If found, return Point object. Else return null.</p> 
    6876                 */ 
    69                 private static function findNext(bmd:BitmapData, startY:int):Point 
    70                 { 
    71                         for(var y:int = startY; y < bmd.height; y++) 
     77                private static function findNext(bmd:BitmapData, pt:Point):Boolean 
     78                { 
     79                        for(var y:int = pt.y; y < bmd.height; y++) 
    7280                        { 
    7381                                for(var x:int = 0; x < bmd.width; x++) 
     
    7583                                        if(bmd.getPixel(x, y) == 0x000000) 
    7684                                        { 
    77                                                 return new Point(x, y); 
     85                                                pt.x = x; 
     86                                                pt.y = y; 
     87                                                return true; 
    7888                                        } 
    7989                                } 
    8090                        } 
    8191 
    82                         return null
     92                        return false
    8393                } 
    8494 
     
    160170                 *  Note: the path must be within the dimensions of the pixmap. 
    161171                 */ 
    162                 private static function xorPath(bm:BitmapData, p:Object):void 
    163                 { 
    164                         if(p.priv.length <= 0)  // a path of length 0 is silly, but legal 
    165                         { 
    166                                 return; 
    167                         } 
    168  
    169                         var y1:int = p.priv[p.priv.length - 1].y; 
    170  
    171                         var xa:int = p.priv[0].x; 
    172                         for(var k:int = 0; k < p.priv.length; k++) 
    173                         { 
    174                                 var x:int = p.priv[k].x; 
    175                                 var y:int = p.priv[k].y; 
     172                private static function xorPath(bm:BitmapData, p:Object, filter:ColorMatrixFilter):void 
     173                { 
     174                        var priv:Array = p.priv as Array; 
     175                        var len:int = priv.length; 
     176 
     177                        // get minimum x 
     178                        var minX:int = 99999; 
     179                        for(var i:int = 0; i < len; i++) 
     180                        { 
     181                                minX = Math.min(minX, priv[i].x); 
     182                        } 
     183 
     184                        var y1:int = priv[len - 1].y; 
     185                        var pt:Point = new Point(); 
     186                        var rect:Rectangle = new Rectangle; 
     187                        for(i = 0; i < len; i++) 
     188                        { 
     189                                var x:int = priv[i].x; 
     190                                var y:int = priv[i].y; 
    176191 
    177192                                if(y != y1) 
    178193                                { 
    179                                         // efficiently invert the rectangle [x,xa] x [y,y1] 
    180                                         xorToRef(bm, x, Math.max(y, y1), xa); 
     194                                        // efficiently invert the rectangle [minX, x] x [y,y1] 
     195                                        var y2:int = Math.max(y, y1); 
     196                                        pt.x = minX; pt.y = y2; 
     197                                        rect.x = minX; rect.y = y2; rect.width = x - minX; rect.height = 1; 
     198                                        bm.applyFilter(bm, rect, pt, filter); 
    181199                                        y1 = y; 
    182200                                } 
    183201                        } 
    184                 } 
    185  
    186                 /** 
    187                  *  decompose image into paths efficiently invert bits [x,infty) and [xa,infty) in line y. 
    188                  * 
    189                  *  Here xa must be a multiple of BM_WORDBITS. 
    190                  */ 
    191                 private static function xorToRef(bm:BitmapData, x:int, y:int, xa:int):void 
    192                 { 
    193                         // XOR 
    194                         var filter:ColorMatrixFilter = new ColorMatrixFilter([ 
    195                                 -1, 0, 0, 0, 255,  
    196                                 -1, 0, 0, 0, 255,  
    197                                 -1, 0, 0, 0, 255, 
    198                                  0, 0, 0, 1, 0 
    199                         ]); 
    200  
    201                         bm.applyFilter(bm, new Rectangle(0, y, x, 1), new Point(0, y), filter); 
    202202                } 
    203203        } 
  • nitoyon/as3/src/com/nitoyon/potras/ProcessPath.as

    r85 r91  
    115115                        var ct:Array; 
    116116                        var dir:int; 
    117                         var constraint:Array = []; 
    118117                        var k1:int; 
     118                        var constraint0:Point = new Point(); 
     119                        var constraint1:Point = new Point(); 
     120                        var cur:Point = new Point(); 
     121                        var off:Point = new Point(); 
     122                        var dk:Point = new Point(); 
    119123                        for(i = n - 1; i >= 0; i--) 
    120124                        { 
    121                                 //trace("=========="); 
    122125                                ct = [0, 0, 0, 0]; 
    123126 
     
    125128                                dir = (3 + 3 * (pt[mod(i + 1, n)].x - pt[i].x) + (pt[mod(i + 1, n)].y - pt[i].y)) / 2; 
    126129                                ct[dir]++; 
    127                                 constraint[0] = new Point(0, 0); 
    128                                 constraint[1] = new Point(0, 0); 
     130                                constraint0.x = constraint0.y = constraint1.x = constraint1.y = 0; 
    129131 
    130132                                // find the next k such that no straight line from i to k 
     
    137139                                        ct[dir]++; 
    138140 
    139                                         //trace("dir: ", dir, ", ct: ", ct); 
    140  
    141141                                        // if all four "directions" have occurred, cut this path 
    142142                                        if(ct[0] && ct[1] && ct[2] && ct[3]) 
     
    147147                                        } 
    148148 
    149                                         var cur:Point = new Point(pt[k].x - pt[i].x, pt[k].y - pt[i].y)
    150                                         //trace("cur: ", cur)
     149                                        cur.x = pt[k].x - pt[i].x
     150                                        cur.y = pt[k].y - pt[i].y
    151151 
    152152                                        // see if current constraint is violated 
    153                                         if(xprod(constraint[0], cur) > 0 || xprod(constraint[1], cur) < 0) 
     153                                        if(xprod(constraint0, cur) > 0 || xprod(constraint1, cur) < 0) 
    154154                                        { 
    155155                                                break; 
     
    163163                                        else 
    164164                                        { 
    165                                                 var off:Point = new Point( 
    166                                                         cur.x + ((-cur.y >= 0 && (-cur.y > 0 || cur.x < 0)) ? 1 : -1),  
    167                                                         cur.y + ((-cur.x <= 0 && (-cur.x < 0 || cur.y < 0)) ? 1 : -1)); 
    168                                                 //trace("off1 = ", off); 
    169                                                 if(xprod(constraint[0], off) <= 0) 
     165                                                off.x = cur.x + ((-cur.y >= 0 && (-cur.y > 0 || cur.x < 0)) ? 1 : -1); 
     166                                                off.y = cur.y + ((-cur.x <= 0 && (-cur.x < 0 || cur.y < 0)) ? 1 : -1); 
     167                                                if(xprod(constraint0, off) <= 0) 
    170168                                                { 
    171                                                         constraint[0] = off; 
     169                                                        constraint0.x = off.x; 
     170                                                        constraint0.y = off.y; 
    172171                                                } 
    173172 
    174                                                 off = new Point( 
    175                                                         cur.x + ((-cur.y <= 0 && (-cur.y < 0 || cur.x < 0)) ? 1 : -1),  
    176                                                         cur.y + ((-cur.x >= 0 && (-cur.x > 0 || cur.y < 0)) ? 1 : -1)) 
    177                                                 //trace("off2 = ", off); 
    178                                                 if(xprod(constraint[1], off) >= 0) 
     173                                                off.x = cur.x + ((-cur.y <= 0 && (-cur.y < 0 || cur.x < 0)) ? 1 : -1); 
     174                                                off.y = cur.y + ((-cur.x >= 0 && (-cur.x > 0 || cur.y < 0)) ? 1 : -1); 
     175                                                if(xprod(constraint1, off) >= 0) 
    179176                                                { 
    180                                                         constraint[1] = off; 
     177                                                        constraint1.x = off.x; 
     178                                                        constraint1.y = off.y; 
    181179                                                } 
    182  
    183                                                 //trace("constraint: ", constraint[0], constraint[1]); 
    184180                                        } 
    185181 
    186182                                        k1 = k; 
    187183                                        k = nc[k1]; 
    188                                         //trace("k, k1 = ", k, k1); 
    189184                                        if(!cyclic(k, i, k1)) 
    190185                                        { 
    191186                                                break; 
    192187                                        } 
    193  
    194                                         //trace("---"); 
    195                                 } 
    196  
    197                                 //trace("-"); 
     188                                } 
    198189 
    199190                                // constraint 
    200191                                if(!foundk) 
    201192                                { 
    202                                         var dk:Point = new Point(sign(pt[k].x-pt[k1].x), sign(pt[k].y-pt[k1].y)); 
    203                                         cur = new Point(pt[k1].x - pt[i].x, pt[k1].y - pt[i].y); 
    204  
    205                                         // find largest integer j such that xprod(constraint[0], cur+j*dk) >= 0  
    206                                         // and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity of xprod. 
    207                                         var a:int = xprod(constraint[0], cur); 
    208                                         var b:int = xprod(constraint[0], dk); 
    209                                         var c:int = xprod(constraint[1], cur); 
    210                                         var d:int = xprod(constraint[1], dk); 
     193                                        dk.x = sign(pt[k].x-pt[k1].x); 
     194                                        dk.y = sign(pt[k].y-pt[k1].y); 
     195                                        cur.x = pt[k1].x - pt[i].x; 
     196                                        cur.y = pt[k1].y - pt[i].y; 
     197 
     198                                        // find largest integer j such that xprod(constraint0, cur+j*dk) >= 0  
     199                                        // and xprod(constraint1, cur+j*dk) <= 0. Use bilinearity of xprod. 
     200                                        var a:int = xprod(constraint0, cur); 
     201                                        var b:int = xprod(constraint0, dk); 
     202                                        var c:int = xprod(constraint1, cur); 
     203                                        var d:int = xprod(constraint1, dk); 
    211204 
    212205                                        // find largest integer j such that a+j*b>=0 and c+j*d<=0. 
     
    219212                                        if(d < 0) 
    220213                                        { 
    221                                                 //trace("j : ", j); 
    222214                                                j = Math.min(j, floordiv(c, -d)); 
    223                                                 //trace("j : ", j); 
    224215                                        } 
    225216                                        pivk[i] = mod(k1 + j, n); 
    226  
    227                                         //trace("dk      = ", dk); 
    228                                         //trace("cur     = ", cur); 
    229                                         //trace("a,b,c,d = ", a, b, c, d); 
    230                                         //trace("k1, j, n= ", k1, j, n, floordiv(c, -d)); 
    231                                         //trace("pivk[i] = ", pivk[i]); 
    232                                 } 
    233  
    234                                 //trace("----------------"); 
     217                                } 
    235218 
    236219                                // foundk 
     
    239222                        // clean up: for each i, let lon[i] be the largest k such that for 
    240223                        // all i' with i<=i'<k, i'<k<=pivk[i']. 
    241                         j = pivk[n-1]; 
     224                        j = pivk[n - 1]; 
    242225                        lon[n - 1] = j; 
    243226                        for(i = n - 2; i >= 0; i--) 
     
    248231                                } 
    249232                                lon[i] = j; 
    250  
    251                                 //trace("pivk[" + i + "]:", pivk[i] + ", lon[" + i + "]:", lon[i]); 
    252233                        } 
    253234 
     
    349330                                        } 
    350331                                        pen[i] = best; 
    351                                         //trace(i, best); 
    352332                                } 
    353333                        } 
     
    357337                        for(i = n, j = m - 1; i > 0; j--) 
    358338                        { 
    359                                 i = prev[i]; 
    360                                 po[j] = i; 
     339                                po[j] = i = prev[i]; 
    361340                        } 
    362341 
     
    415394                        var n:int = pt.length; 
    416395 
    417                         var p0:Point = pt[0].clone(); 
    418  
    419396                        var i:int, j:int, k:int, l:int; 
    420  
    421                         var vertex:Array = []; 
    422  
    423                         // calculate "optimal" point-slope representation for each line segment 
    424                         var ctr:Array = []; 
    425                         var dir:Array = []; 
    426                         for(i = 0; i < m; i++) 
    427                         { 
    428                                 j = po[mod(i + 1, m)]; 
    429                                 j = mod(j - po[i], n) + po[i]; 
    430  
    431                                 ctr[i] = new Point(); 
    432                                 dir[i] = new Point(); 
    433  
    434                                 pointslope(pt, sums, po[i], j, ctr[i], dir[i]); 
    435                         } 
    436397 
    437398                        // represent each line segment as a singular quadratic form; the 
     
    440401                        var q:Array = []; 
    441402                        var v:Point3D = new Point3D(); 
     403                        var ctr:Point = new Point(); 
     404                        var dir:Point = new Point(); 
    442405                        for(i = 0; i < m; i++) 
    443406                        { 
     407                                // calculate "optimal" point-slope representation for each line segment 
     408                                j = po[(i + 1) % m]; 
     409                                j = mod(j - po[i], n) + po[i]; 
     410                                ctr.x = ctr.y = dir.x = dir.y = 0; 
     411                                pointslope(pt, sums, po[i], j, ctr, dir); 
     412 
    444413                                q[i] = new QuadraticForm(); 
    445  
    446                                 var d1:Number = Math.pow(dir[i].x, 2) + Math.pow(dir[i].y, 2); 
    447                                 if(d1 == 0.0) 
    448                                 { 
    449                                         q[i] = new QuadraticForm(); 
    450                                 } 
    451                                 else 
    452                                 { 
    453                                         v = new Point3D(dir[i].y, -dir[i].x, 0); 
    454                                         v[2] = -v[1] * ctr[i].y - v[0] * ctr[i].x 
    455                                         q[i] = v.multiplyTranspose().scalar(1 / d1); 
     414                                var d1:Number = dir.x * dir.x + dir.y * dir.y; 
     415                                if(d1 != 0.0) 
     416                                { 
     417                                        v[0] = dir.y; 
     418                                        v[1] = -dir.x; 
     419                                        v[2] = -v[1] * ctr.y - v[0] * ctr.x 
     420                                        q[i].fromVectorMultiply(v).scalar(1 / d1); 
    456421                                } 
    457422                        } 
     
    461426                        // within a given unit square which minimizes the square distance to 
    462427                        // the two lines. 
     428                        var vertex:Array = []; 
     429                        var p0:Point = pt[0].clone(); 
     430                        var s:Point = new Point(); 
     431                        var w:Point = new Point(); 
     432                        var _q:QuadraticForm = new QuadraticForm(); 
     433                        var minCoord:Point = new Point; 
    463434                        for(i = 0; i < m; i++) 
    464435                        { 
    465                                 var Q:QuadraticForm = new QuadraticForm(); 
    466436                                var z:int; 
     437                                vertex[i] = new Point(); 
    467438 
    468439                                // let s be the vertex, in coordinates relative to x0/y0 
    469                                 var s:Point = pt[po[i]].subtract(p0); 
     440                                s.x = pt[po[i]].x - p0.x; 
     441                                s.y = pt[po[i]].y - p0.y; 
    470442 
    471443                                // intersect segments i-1 and i 
     
    473445 
    474446                                // add quadratic forms 
    475                                 Q = q[j].add(q[i]); 
    476  
    477                                 var w:Point = new Point(); 
     447                                var Q:QuadraticForm = q[j].clone().add(q[i]); 
     448 
    478449                                while(1) 
    479450                                { 
    480451                                        // minimize the quadratic form Q on the unit square 
    481452                                        // find intersection 
    482  
    483453                                        var det:Number = Q[0][0] * Q[1][1] - Q[0][1] * Q[1][0]; 
    484454                                        if(det != 0.0) 
     
    509479                                        var d:Number = v[0] * v[0] + v[1] * v[1]; 
    510480                                        v[2] = - v[1] * s.y - v[0] * s.x; 
    511                                         Q = Q.add(v.multiplyTranspose().scalar(1 / d)); 
     481                                        Q.add(_q.fromVectorMultiply(v)).scalar(1 / d); 
    512482                                } 
    513483 
     
    516486                                if(dx <= .5 && dy <= .5) 
    517487                                { 
    518                                         vertex[i] = w.add(p0); 
     488                                        vertex[i].x = w.x + p0.x; 
     489                                        vertex[i].y = w.y + p0.y; 
    519490                                        continue; 
    520491                                } 
     
    523494                                // on boundary of square 
    524495                                var min:Number, cand:Number; // minimum and candidate for minimum of quad. form 
    525                                 var minCoord:Point = new Point();                              // coordinates of minimum 
     496                                minCoord.x = s.x; minCoord.y = s.y; // coordinates of minimum 
    526497                                min = Q.apply(s); 
    527                                 minCoord = s.clone(); 
    528498 
    529499                                if(Q[0][0] != 0.0) 
     
    533503                                                w.y = s.y - 0.5 + z; 
    534504                                                w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0]; 
    535                                                 dx = Math.abs(w.x - s.x); 
     505                                                dx = (w.x - s.x > 0 ? w.x - s.x : s.x - w.x); 
    536506                                                cand = Q.apply(w); 
    537507                                                if(dx <= .5 && cand < min) 
    538508                                                { 
    539509                                                        min = cand; 
    540                                                         minCoord = w.clone()
     510                                                        minCoord.x = w.x; minCoord.y = w.y
    541511                                                } 
    542512                                        } 
     
    549519                                                w.x = s.x - 0.5 + z; 
    550520                                                w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1]; 
    551                                                 dy = Math.abs(w.y - s.y); 
     521                                                dy = (w.y - s.y > 0 ? w.y - s.y : s.y - w.y); 
    552522                                                cand = Q.apply(w); 
    553523                                                if(dy <= .5 && cand < min) 
    554524                                                { 
    555525                                                        min = cand; 
    556                                                         minCoord = w.clone()
     526                                                        minCoord.x = w.x; minCoord.y = w.y
    557527                                                } 
    558528                                        } 
     
    564534                                        for(k = 0; k < 2; k++) 
    565535                                        { 
    566                                                 w = new Point(s.x - 0.5 + l, s.y - 0.5 + k); 
     536                                                w.x = s.x - 0.5 + l; 
     537                                                w.y = s.y - 0.5 + k; 
    567538                                                cand = Q.apply(w); 
    568539                                                if(cand < min) 
    569540                                                { 
    570541                                                        min = cand; 
    571                                                         minCoord = w.clone()
     542                                                        minCoord.x = w.x; minCoord.y = w.y
    572543                                                } 
    573544                                        } 
    574545                                } 
    575546 
    576                                 vertex[i] = minCoord.add(p0); 
     547                                vertex[i].x = minCoord.x + p0.x; 
     548                                vertex[i].y = minCoord.y + p0.y; 
    577549                                continue; 
    578550                        } 
     
    596568                        { 
    597569                                // reverse orientation of negative paths 
     570                                var tmp:Point; 
    598571                                for(i = 0, j = m - 1; i < j; i++, j--) 
    599572                                { 
    600                                         var tmp:Point = vertex[i].clone()
     573                                        tmp = vertex[i]
    601574                                        vertex[i] = vertex[j]; 
    602575                                        vertex[j] = tmp; 
     
    605578 
    606579                        // examine each vertex and find its best fit 
     580                        var p2:Point = new Point(); 
     581                        var p3:Point = new Point(); 
     582                        var p4:Point = new Point(); 
    607583                        for(i = 0; i < m; i++) 
    608584                        { 
    609                                 var j:int = mod(i + 1, m)
    610                                 var k:int = mod(i + 2, m)
    611                                 var p4:Point = interval(1 / 2.0, vertex[k], vertex[j]); 
     585                                var j:int = (i + 1) % m
     586                                var k:int = (i + 2) % m
     587                                interval(1 / 2.0, vertex[k], vertex[j], p4); 
    612588 
    613589                                var curve:Curve = new Curve(); 
    614                                 curve.vertex = vertex[j].clone(); 
     590                                curve.vertex.x =vertex[j].x; 
     591                                curve.vertex.y =vertex[j].y; 
    615592 
    616593                                var denom:Number = ddenom(vertex[i], vertex[k]); 
     594                                var alpha:Number; 
    617595                                if(denom != 0.0) 
    618596                                { 
    619597                                        var dd:Number = dpara(vertex[i], vertex[j], vertex[k]) / denom; 
    620                                         dd = Math.abs(dd); 
    621                                         var alpha:Number = dd > 1 ? (1 - 1.0 / dd) : 0; 
    622                                         alpha = alpha / 0.75; 
     598                                        dd = dd < 0 ? -dd : dd; 
     599                                        alpha = dd > 1 ? (1 - 1.0 / dd) / 0.75 : 0; 
    623600                                } 
    624601                                else 
     
    631608                                { 
    632609                                        curve.tag  = POTRACE_CORNER; 
    633                                         curve.c[0] = new Point()
    634                                         curve.c[1] = vertex[j]
    635                                         curve.c[2] = p4
     610                                        curve.c[0].x = 0; curve.c[0].y = 0
     611                                        curve.c[1].x = vertex[j].x; curve.c[1].y = vertex[j].y
     612                                        curve.c[2].x = p4.x; curve.c[2].y = p4.y
    636613                                } 
    637614                                else 
     
    645622                                                alpha = 1; 
    646623                                        } 
    647                                         var p2:Point = interval(.5 + .5 * alpha, vertex[i], vertex[j]); 
    648                                         var p3:Point = interval(.5 + .5 * alpha, vertex[k], vertex[j]); 
     624                                        interval(.5 + .5 * alpha, vertex[i], vertex[j], p2); 
     625                                        interval(.5 + .5 * alpha, vertex[k], vertex[j], p3); 
    649626                                        curve.tag = POTRACE_CURVETO; 
    650                                         curve.c[0] = p2
    651                                         curve.c[1] = p3
    652                                         curve.c[2] = p4
     627                                        curve.c[0].x = p2.x; curve.c[0].y = p2.y
     628                                        curve.c[1].x = p3.x; curve.c[1].y = p3.y
     629                                        curve.c[2].x = p4.x; curve.c[2].y = p4.y
    653630                                } 
    654631                                curve.alpha = alpha; // store the "cropped" value of alpha 
     
    745722                 *  range over the straight line segment [a,b] when lambda ranges over [0,1] 
    746723                 */ 
    747                 public static function interval(lambda:Number, a:Point, b:Point):Point 
    748                 { 
    749                         return new Point( 
    750                                 a.x + lambda * (b.x - a.x), 
    751                                 a.y + lambda * (b.y - a.y) 
    752                                 ); 
     724                public static function interval(lambda:Number, a:Point, b:Point, ret:Point):void 
     725                { 
     726                        ret.x = a.x + lambda * (b.x - a.x); 
     727                        ret.y = a.y + lambda * (b.y - a.y); 
    753728                } 
    754729 
     
    854829import flash.utils.flash_proxy; 
    855830import flash.errors.IllegalOperationError; 
    856 import mx.utils.StringUtil; 
    857831 
    858832internal class Point3D extends Proxy 
     
    886860        } 
    887861 
    888         public function multiplyTranspose():QuadraticForm 
    889         { 
    890                 var matrix:QuadraticForm = new QuadraticForm(); 
    891  
    892                 for(var i:int = 0; i < 3; i++) 
    893                 { 
    894                         for(var j:int = 0; j < 3; j++) 
    895                         { 
    896                                 matrix[i][j] = $v[i] * $v[j]; 
    897                         } 
    898                 } 
    899                 return matrix; 
    900         } 
    901  
    902862        public function toString():String 
    903863        { 
    904                 return StringUtil.substitute( 
    905                         "({0},{1},{2})",  
    906                         $v[0], $v[1], $v[2]); 
     864                return "(" + $v[0] + "," + $v[1] + "," + $v[2] + ")"; 
    907865        } 
    908866} 
     
    961919        } 
    962920 
     921        public function clone():QuadraticForm 
     922        { 
     923                var ret:QuadraticForm = new QuadraticForm(); 
     924                for(var i:int = 0; i < 3; i++) 
     925                { 
     926                        for(var j:int = 0; j < 3; j++) 
     927                        { 
     928                                ret[i][j] = $m[i][j]; 
     929                        } 
     930                } 
     931                return ret; 
     932        } 
     933 
    963934        public function add(m2:QuadraticForm):QuadraticForm 
    964935        { 
    965                 var ret:QuadraticForm = new QuadraticForm(); 
    966  
    967936                for(var i:int = 0; i < 3; i++) 
    968937                { 
    969938                        for(var j:int = 0; j < 3; j++) 
    970939                        { 
    971                                 ret[i][j] = $m[i][j] + m2[i][j]; 
    972                         } 
    973                 } 
    974                 return ret
     940                                $m[i][j] += m2[i][j]; 
     941                        } 
     942                } 
     943                return this
    975944        } 
    976945 
    977946        public function scalar(s:Number):QuadraticForm 
    978947        { 
    979                 var ret:QuadraticForm = new QuadraticForm(); 
    980  
    981948                for(var i:int = 0; i < 3; i++) 
    982949                { 
    983950                        for(var j:int = 0; j < 3; j++) 
    984951                        { 
    985                                 ret[i][j] = $m[i][j] * s; 
    986                         } 
    987                 } 
    988                 return ret; 
     952                                $m[i][j] *= s; 
     953                        } 
     954                } 
     955                return this; 
     956        } 
     957 
     958        public function fromVectorMultiply(v:Point3D):QuadraticForm 
     959        { 
     960                for(var i:int = 0; i < 3; i++) 
     961                { 
     962                        for(var j:int = 0; j < 3; j++) 
     963                        { 
     964                                $m[i][j] = v[i] * v[j]; 
     965                        } 
     966                } 
     967                return this; 
    989968        } 
    990969 
    991970        public function toString():String 
    992971        { 
    993                 return StringUtil.substitute( 
    994                         "[({0},{1},{2}), ({3},{4},{5}), ({6},{7},{8})]",  
    995                         $m[0][0], $m[0][1], $m[0][2],  
    996                         $m[1][0], $m[1][1], $m[1][2],  
    997                         $m[2][0], $m[2][1], $m[2][2]); 
     972                return "[" +  
     973                        $m[0][0] + "," + $m[0][1] + "," + $m[0][2] + "," +  
     974                        $m[1][0] + "," + $m[1][1] + "," + $m[1][2] + "," +  
     975                        $m[2][0] + "," + $m[2][1] + "," + $m[2][2] + "]"; 
    998976        } 
    999977}