Example #1
0
int gridkmap_xy2ij(gridkmap* gm, double x, double y, int* iout, int* jout)
{
    double* minmax = kd_getminmax(gm->tree);
    double pos[2];
    size_t nearest;
    size_t id;
    poly* p;
    int i, j, i1, i2, j1, j2;
    int success = 0;

    if (x < minmax[0] || y < minmax[1] || x > minmax[2] || y > minmax[3])
        return success;

    pos[0] = x;
    pos[1] = y;
    nearest = kd_findnearestnode(gm->tree, pos);
    id = kd_getnodeorigid(gm->tree, nearest);
    p = poly_create();

    j = id / (gm->nce1 + 1);
    i = id % (gm->nce1 + 1);

    i1 = (i > 0) ? i - 1 : i;
    i2 = (i < gm->nce1) ? i + 1 : i;
    j1 = (j > 0) ? j - 1 : j;
    j2 = (j < gm->nce2) ? j + 1 : j;

    /*
     * TODO?: looks a bit heavyweight
     */
    for (j = j1; j <= j2 - 1; ++j)
        for (i = i1; i <= i2 - 1; ++i) {
            if (!isfinite(gm->gx[j][i]) || !isfinite(gm->gx[j][i + 1]) || !isfinite(gm->gx[j + 1][i + 1]) || !isfinite(gm->gx[j + 1][i]))
                continue;
            poly_addpoint(p, gm->gx[j][i], gm->gy[j][i]);
            poly_addpoint(p, gm->gx[j][i + 1], gm->gy[j][i + 1]);
            poly_addpoint(p, gm->gx[j + 1][i + 1], gm->gy[j + 1][i + 1]);
            poly_addpoint(p, gm->gx[j + 1][i], gm->gy[j + 1][i]);
            poly_addpoint(p, gm->gx[j][i], gm->gy[j][i]);

            if (poly_containspoint(p, x, y)) {
                success = 1;
                *iout = i;
                *jout = j;
                goto finish;
            }
            poly_clear(p);
        }

  finish:

    poly_destroy(p);

    return success;
}
Example #2
0
/** Forms polyline boundary around a grid in index space.
 * @param nce1 Number of cells in X direction
 * @param nce2 Number of cells in Y direction
 * @param x X coordinates of grid nodes
 * @return Boundary polyline
 */
poly* poly_formboundij(int nce1, int nce2, double** x)
{
    poly* pl = poly_create();
    int direction = 0;          /* 0 - down, 1 - right, 2 - up, 3 -left */
    int iinc[] = { 0, 1, 0, -1 };
    int jinc[] = { 1, 0, -1, 0 };
    int i, j, istart, jstart;

    for (j = 0; j <= nce2; ++j)
        for (i = 0; i <= nce1; ++i)
            if (!isnan(x[j][i]))
                goto ok;

  ok:
    if (j > nce2)
        return pl;

    istart = i;
    jstart = j;
    poly_addpoint(pl, i, j);

    do {
        int direction_stop = (direction + 2) % 4;
        int inext, jnext;

        direction = (direction + 3) % 4;
        inext = i + iinc[direction];
        jnext = j + jinc[direction];

        while ((inext < 0 || jnext < 0 || inext > nce1 || jnext > nce2 || isnan(x[jnext][inext])) && direction != direction_stop) {
            direction = (direction + 1) % 4;
            inext = i + iinc[direction];
            jnext = j + jinc[direction];
        }

        if (direction == direction_stop)
            break;

        i = inext;
        j = jnext;

        poly_addpoint(pl, i, j);

    } while (j != jstart || i != istart);

    poly_close(pl);

    return (pl);
}
Example #3
0
/* Cuts boundary polygon in two. 
 * The cut goes either horizontally ([fixed][changes]) or vertically 
 * ([changes][fixed]) in index space; the physical nodes are given by
 * input double arrays; first two intersections of the cutting polyline
 * with the polygon are used to form the new polygons.
 * @param pl Original polygon
 * @param gx Array of x cell corner coordinates
 * @param gy Array of y cell corner coordinates
 * @param horiz flag: 1 for horizontal cut; 0 otherwise
 * @param index Value of "fixed" index
 * @param start Start value of "variable" index
 * @param end End value of "variable" index
 * @param pl1 Output polygon 1
 * @param pl1 Output polygon 2
 */
static void cut_boundary(poly* pl, double** gx, double** gy, int horiz, int index, int start, int end, poly** pl1, poly** pl2)
{
    int n = pl->n;
    int i = -1;
    int i1 = -1;                /* array index of the first intersection */
    int i2 = -1;                /* array index of the second intersection */
    int ii1 = -1;               /* polygon index of the first intersection */
    int ii2 = -1;               /* polygon index of the second intersection */
    int tmp = -1;

    /*
     * if the polygon has been explicitely closed, ignore the last point 
     */
    if (poly_isclosed(pl, 1.0e-15))
        n--;

    if (horiz) {                /* horizontal cut */
        /*
         * find first intersection 
         */
        for (i = start; i < end; ++i) {
            ii1 = poly_findindex(pl, gx[index][i], gy[index][i]);
            if (ii1 < 0)
                /*
                 * this node does not belong to the boundary 
                 */
                continue;
            /*
             * this node belongs to the boundary polygon To accept it as a
             * valid intersection, we must ensure that the very next node is 
             * either inside the polygon or belongs to the boundary but is
             * not the next boundary node. 
             */
            tmp = poly_findindex(pl, gx[index][i + 1], gy[index][i + 1]);
            if ((tmp < 0 && poly_containspoint(pl, gx[index][i + 1], gy[index][i + 1])) || (tmp >= 0 && abs(tmp - ii1) > 1 && abs(tmp - ii1) < n - 1))
                break;
        }

        /*
         * how the for-cycle ended 
         */
        if (i < end)            /* ok */
            i1 = i;
        else                    /* no intersection found */
            return;

        /*
         * find second intersection start from the node next to the first
         * intersection 
         */
        for (i = i1 + 1; i <= end; ++i) {
            ii2 = poly_findindex(pl, gx[index][i], gy[index][i]);
            if (ii2 >= 0)
                /*
                 * this node must be inside the boundary polygon -- skip 
                 */
                break;
        }

        if (ii2 < 0)
            /*
             * no intersection found 
             */
            return;
        else
            /*
             * ok 
             */
            i2 = i;

        /*
         * we found all necessary details, now form the new polygons 
         */
        *pl1 = poly_create();
        *pl2 = poly_create();

        /*
         * add the portion of perimeter 
         */
        for (i = ii1; i != ii2; i = (i + 1) % n)
            poly_addpoint(*pl1, pl->x[i], pl->y[i]);
        /*
         * add the cutting section 
         */
        for (i = i2; i > i1; --i)
            poly_addpoint(*pl1, gx[index][i], gy[index][i]);

        /*
         * add the portion of perimeter 
         */
        for (i = ii2; i != ii1; i = (i + 1) % n)
            poly_addpoint(*pl2, pl->x[i], pl->y[i]);
        /*
         * add the cutting section 
         */
        for (i = i1; i < i2; ++i)
            poly_addpoint(*pl2, gx[index][i], gy[index][i]);

    } else {                    /* vertical cut */
        for (i = start; i < end; ++i) {
            ii1 = poly_findindex(pl, gx[i][index], gy[i][index]);
            if (ii1 < 0)
                continue;
            tmp = poly_findindex(pl, gx[i + 1][index], gy[i + 1][index]);
            if ((tmp < 0 && poly_containspoint(pl, gx[i + 1][index], gy[i + 1][index])) || (tmp >= 0 && abs(tmp - ii1) > 1 && abs(tmp - ii1) < n - 1))
                break;
        }

        if (i < end)
            i1 = i;
        else
            return;

        for (i = i1 + 1; i <= end; ++i) {
            ii2 = poly_findindex(pl, gx[i][index], gy[i][index]);
            if (ii2 >= 0)
                break;
        }

        if (ii2 < 0)
            return;
        else
            i2 = i;

        *pl1 = poly_create();
        *pl2 = poly_create();

        for (i = ii1; i != ii2; i = (i + 1) % n)
            poly_addpoint(*pl1, pl->x[i], pl->y[i]);
        for (i = i2; i > i1; --i)
            poly_addpoint(*pl1, gx[i][index], gy[i][index]);

        for (i = ii2; i != ii1; i = (i + 1) % n)
            poly_addpoint(*pl2, pl->x[i], pl->y[i]);
        for (i = i1; i < i2; ++i)
            poly_addpoint(*pl2, gx[i][index], gy[i][index]);
        /*
         * There used to be closure of the polylines here:
         *        poly_close(*pl1);
         *        poly_close(*pl2);
         * While this does not harm, it causes the boundary of a quadrilateral
         * to contain 5 points rather than 4, which caused allocation for 8
         * points... Anyway, considering the way search in poly_containspoint()
         * works, this is not necessary.
         */
    }
}
int main (void) {

   poly *P0, *P1, *P2, *P3, *M1, *M2, *P4, *P5, *P6, *P7;

   P0=poly_create(4,2,1,3,2,6,5,1,7); //4 terms: 1x^7 + 6x^5 + 3x^2 + 2x^1
   P1=poly_create(3,3,2,1,4,6,5);     //3 terms: 6x^5 + 1x^4 + 3x^2
   P2=poly_create(1,16,2);            //1 term:  16x^2
   P3=poly_create(0);                 // no terms

   printf("P0: "); poly_print(P0);
   printf("P1: "); poly_print(P1);
   printf("P2: "); poly_print(P2);
   printf("P3: "); poly_print(P3);

   M1=poly_scalar_mult(P1,2);
   printf("M1 (P1*2): "); poly_print(M1);

   M2=poly_scalar_mult(P3,4);
   printf("M2 (P3*4): "); poly_print(M2);

   P4=poly_duplicate(M1);
   printf("P4 (dup M1): "); poly_print(P4);

   P5=poly_add(P1,P0);
   printf("P5 (P1+P0): "); poly_print(P5);

   P6=poly_add(P3,P3);
   printf("P6 (P3+P3): "); poly_print(P6); 

   P7=poly_add(P0,P3);
   printf("P7 (P0+P3): "); poly_print(P7);

   poly_free(&P1);
   if (P1==NULL) printf("P1: was freed\n");
   else          printf("P1: is not null!!\n");
   
   
   
   poly *test1=poly_create(4,2,1,3,2,6,5,1,7); //4 terms: 1x^7 + 6x^5 + 3x^2 + 2x^1

   poly *test2=poly_duplicate(test1);
   test2=poly_scalar_mult(test2, 5);

   printf("test1: ");poly_print(test1);
   printf("test2: ");poly_print(test2);

   //printf("%p, %p\n", test1, test2);
   poly_free(&test1);

   poly *MM1 = poly_create(5,1,1,2,2,3,3,4,4,5,5);
   poly *MM2 = poly_create(5,-1,1,-2,2,-3,3,-4,4,-5,5);

   printf("MM1: ");poly_print(MM1);
   printf("MM2: ");poly_print(MM2);


   poly *MM1_Plus_MM2 = poly_add(MM1, MM2);
   printf("(MM1+MM2): ");poly_print(MM1_Plus_MM2);

   poly *MM1_Multiplied_By_5 = poly_scalar_mult(MM1, 5);
   poly *MM2_Multiplied_By_10 = poly_scalar_mult(MM2, 10);

   printf("MM1*5: ");poly_print(MM1_Multiplied_By_5);
   printf("MM2*10: ");poly_print(MM2_Multiplied_By_10);
   printf("MM1: ");poly_print(MM1);
   printf("MM2: ");poly_print(MM2);

}