Advertisement
greg1996

php

Apr 22nd, 2012
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.64 KB | None | 0 0
  1. private function add_curve(curves, a, cpa, cpb, b) {
  2.         $kind;
  3.         if ((abs(xprodf(new Point(cpa->x - a->x, cpa->y - a->y), new Point(b->x - a->x, b->y - a->y))) < 0->01) &&
  4.             (abs(xprodf(new Point(cpb->x - b->x, cpb->y - b->y), new Point(b->x - a->x, b->y - a->y))) < 0->01)) {
  5.             kind = CurveKind->LINE;
  6.         } else {
  7.             kind = CurveKind->BEZIER;
  8.         }
  9.         if ((kind == CurveKind->LINE)) {
  10.             if ((count(curves) > 0) && (Curve(curves[count(curves) - 1])->kind == CurveKind->LINE)) {
  11.                 $c:Curve = curves[count(curves) - 1] as Curve;
  12.                 if ((abs(xprodf(new Point(c->b->x - c->a->x, c->b->y - c->a->y), new Point(b->x - a->x, b->y - a->y))) < 0->01) && (iprod(c->b, c->a, b) < 0)) {
  13.                     curves[count(curves) - 1] = new Curve(kind, c->a, c->a, c->a, b);
  14.                 } else {
  15.                     curves[] = new Curve(CurveKind->LINE, a, cpa, cpb, b);
  16.                 }
  17.             } else {
  18.                 curves[] = new Curve(CurveKind->LINE, a, cpa, cpb, b);
  19.             }
  20.         } else {
  21.             curves[] = new Curve(CurveKind->BEZIER, a, cpa, cpb, b);
  22.         }
  23.     }
  24.    
  25.     /////////////////////////////////////////////////////////////////////////
  26.     // AUXILIARY FUNCTIONS
  27.     /////////////////////////////////////////////////////////////////////////
  28.    
  29.     /*
  30.      * Return a direction that is 90 degrees counterclockwise from p2-p0,
  31.      * but then restricted to one of the major wind directions (n, nw, w, etc)
  32.      */
  33.    
  34.     private function dorth_infty(p0, p2)Int {
  35.         return new PointInt(-sign(p2->y - p0->y), sign(p2->x - p0->x));
  36.     }
  37.    
  38.     /*
  39.      * Return (p1-p0) x (p2-p0), the area of the parallelogram
  40.      */
  41.     private function dpara(p0, p1, p2) {
  42.         return (p1->x - p0->x) * (p2->y - p0->y) - (p2->x - p0->x) * (p1->y - p0->y);
  43.     }
  44.    
  45.     /*
  46.      * ddenom/dpara have the property that the square of radius 1 centered
  47.      * at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2)
  48.      */
  49.     private function ddenom(p0, p2) {
  50.         $rInt = dorth_infty(p0, p2);
  51.         return r->y * (p2->x - p0->x) - r->x * (p2->y - p0->y);
  52.     }
  53.    
  54.     /*
  55.      * Return true if a <= b < c < a, in a cyclic sense (mod n)
  56.      */
  57.     private function cyclic(a, b, c) {
  58.         if (a <= c) {
  59.             return (a <= b && b < c);
  60.         } else {
  61.             return (a <= b || b < c);
  62.         }
  63.     }
  64.    
  65.     /*
  66.      * Determine the center and slope of the line i->->j-> Assume i < j->
  67.      * Needs "sum" components of p to be set->
  68.      */
  69.     private function pointslope(path:Path, i, j, ctr, dir) {
  70.         // assume i < j
  71.         $n = count(path->pt);
  72.         $sums:Vector-><SumStruct> = path->sums;
  73.         $l;
  74.         $r = 0; // rotations from i to j
  75.        
  76.         while (j >= n) {
  77.             j -= n;
  78.             r++;
  79.         }
  80.         while (i >= n) {
  81.             i -= n;
  82.             r--;
  83.         }
  84.         while (j < 0) {
  85.             j += n;
  86.             r--;
  87.         }
  88.         while (i < 0) {
  89.             i += n;
  90.             r++;
  91.         }
  92.        
  93.         $x = sums[j + 1]->x - sums[i]->x + r * sums[n]->x;
  94.         $y = sums[j + 1]->y - sums[i]->y + r * sums[n]->y;
  95.         $x2 = sums[j + 1]->x2 - sums[i]->x2 + r * sums[n]->x2;
  96.         $xy = sums[j + 1]->xy - sums[i]->xy + r * sums[n]->xy;
  97.         $y2 = sums[j + 1]->y2 - sums[i]->y2 + r * sums[n]->y2;
  98.         $k = j + 1 - i + r * n;
  99.        
  100.         ctr->x = x / k;
  101.         ctr->y = y / k;
  102.        
  103.         $a = (x2 - x * x / k) / k;
  104.         $b = (xy - x * y / k) / k;
  105.         $c = (y2 - y * y / k) / k;
  106.        
  107.         $lambda2 = (a + c + sqrt((a - c) * (a - c) + 4 * b * b)) / 2; // larger e->value
  108.        
  109.         // now find e->vector for lambda2
  110.         a -= lambda2;
  111.         c -= lambda2;
  112.        
  113.         if (abs(a) >= abs(c)) {
  114.             l = sqrt(a * a + b * b);
  115.             if (l != 0) {
  116.                 dir->x = -b / l;
  117.                 dir->y = a / l;
  118.             }
  119.         } else {
  120.             l = sqrt(c * c + b * b);
  121.             if (l != 0) {
  122.                 dir->x = -c / l;
  123.                 dir->y = b / l;
  124.             }
  125.         }
  126.         if (l == 0) {
  127.             // sometimes this can happen when k=4:
  128.             // the two eigenvalues coincide
  129.             dir->x = dir->y = 0;
  130.         }
  131.     }
  132.    
  133.     /*
  134.      * Apply quadratic form Q to vector w = (w->x, w->y)
  135.      */
  136.     private function quadform(Q:Vector-><Vector-><Number>>, w) {
  137.         $sum = 0;
  138.         $v:Vector-><Number> = new Vector-><Number>(3);
  139.         v[0] = w->x;
  140.         v[1] = w->y;
  141.         v[2] = 1;
  142.         for ($i = 0; i < 3; i++) {
  143.             for ($j = 0; j < 3; j++) {
  144.                 sum += v[i] * Q[i][j] * v[j];
  145.             }
  146.         }
  147.         return sum;
  148.     }
  149.    
  150.     /*
  151.      * Calculate point of a bezier curve
  152.      */
  153.     private function bezier(t, p0, p1, p2, p3) {
  154.         $s = 1 - t;
  155.         $res = new Point();
  156.         // Note: a good optimizing compiler (such as gcc-3) reduces the
  157.         // following to 16 multiplications, using common subexpression
  158.         // elimination->
  159.        
  160.         // Note [cw]: Flash: fudeu! ;)
  161.             res->x = s * s * s * p0->x + 3 * (s * s * t) * p1->x + 3 * (t * t * s) * p2->x + t * t * t * p3->x;
  162.         res->y = s * s * s * p0->y + 3 * (s * s * t) * p1->y + 3 * (t * t * s) * p2->y + t * t * t * p3->y;
  163.             return res;
  164.     }
  165.    
  166.     /*
  167.      * Calculate the point t in [0->->1] on the (convex) bezier curve
  168.      * (p0,p1,p2,p3) which is tangent to q1-q0-> Return -1->0 if there is no
  169.      * solution in [0->->1]->
  170.      */
  171.     private function tangent(p0, p1, p2, p3, q0, q1) {
  172.         // (1-t)^2 A + 2(1-t)t B + t^2 C = 0
  173.         $A = cprod(p0, p1, q0, q1);
  174.         $B = cprod(p1, p2, q0, q1);
  175.         $C = cprod(p2, p3, q0, q1);
  176.        
  177.         // a t^2 + b t + c = 0
  178.         $a = A - 2 * B + C;
  179.         $b = -2 * A + 2 * B;
  180.         $c = A;
  181.             $d = b * b - 4 * a * c;
  182.             if (a == 0 || d < 0) {
  183.             return -1;
  184.         }
  185.             $s = sqrt(d);
  186.             $r1 = (-b + s) / (2 * a);
  187.         $r2 = (-b - s) / (2 * a);
  188.             if (r1 >= 0 && r1 <= 1) {
  189.             return r1;
  190.         } else if (r2 >= 0 && r2 <= 1) {
  191.             return r2;
  192.         } else {
  193.             return -1;
  194.         }
  195.     }
  196.    
  197.     /*
  198.      * Calculate distance between two points
  199.      */
  200.     private function ddist(p, q) {
  201.         return sqrt((p->x - q->x) * (p->x - q->x) + (p->y - q->y) * (p->y - q->y));
  202.     }
  203.    
  204.     /*
  205.      * Calculate p1 x p2
  206.      * (Integer version)
  207.      */
  208.     private function xprod(p1Int, p2Int) {
  209.         return p1->x * p2->y - p1->y * p2->x;
  210.     }
  211.    
  212.     /*
  213.      * Calculate p1 x p2
  214.      * (Floating point version)
  215.      */
  216.     private function xprodf(p1, p2) {
  217.         return p1->x * p2->y - p1->y * p2->x;
  218.     }
  219.    
  220.     /*
  221.      * Calculate (p1 - p0) x (p3 - p2)
  222.      */
  223.     private function cprod(p0, p1, p2, p3) {
  224.         return (p1->x - p0->x) * (p3->y - p2->y) - (p3->x - p2->x) * (p1->y - p0->y);
  225.     }
  226.    
  227.     /*
  228.      * Calculate (p1 - p0) * (p2 - p0)
  229.      */
  230.     private function iprod(p0, p1, p2) {
  231.         return (p1->x - p0->x) * (p2->x - p0->x) + (p1->y - p0->y) * (p2->y - p0->y);
  232.     }
  233.    
  234.     /*
  235.      * Calculate (p1 - p0) * (p3 - p2)
  236.      */
  237.     private function iprod1(p0, p1, p2, p3) {
  238.         return (p1->x - p0->x) * (p3->x - p2->x) + (p1->y - p0->y) * (p3->y - p2->y);
  239.     }
  240.    
  241.     private function interval(lambda, a, b) {
  242.         return new Point(a->x + lambda * (b->x - a->x), a->y + lambda * (b->y - a->y));
  243.     }
  244.    
  245.     private function abs(a) {
  246.         return (a > 0) ? a : -a;
  247.     }
  248.    
  249.     private function floordiv(a, n) {
  250.         return (a >= 0) ? a / n : -1 - (-1 - a) / n;
  251.     }
  252.    
  253.     private function mod(a, n) {
  254.         return (a >= n) ? a % n : ((a >= 0) ? a : n - 1 - (-1 - a) % n);
  255.     }
  256.    
  257.     private function sign(x) {
  258.         return (x > 0) ? 1 : ((x < 0) ? -1 : 0);
  259.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement