/* Destroys a subgrid. * @param l Subgrid */ static void subgrid_destroy(subgrid* l) { if (l->half1 != NULL) subgrid_destroy(l->half1); if (l->half2 != NULL) subgrid_destroy(l->half2); poly_destroy(l->bound); free(l); }
Poly *poly_multi(Poly *poly1, Poly *poly2) { Poly *retPoly, *tmpM, *tmpA; // to ensure that no memory leaking during the operation, we use two temporary pointers for memory management purposes // tmpM is used to track the poly object during multiplication // tmpA is used to track the poly object during addition Term *iter; retPoly = poly_new(); for (iter = poly2->head; iter != NULL; iter = iter->next) { tmpM = poly_term_multi(poly1, iter); tmpA = retPoly; retPoly = poly_add(retPoly, tmpM); poly_destroy(tmpM); poly_destroy(tmpA); } return retPoly; }
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; }
int main(int argc, char* argv[]) { char* fname = NULL; int ij = 0; int compact = 0; NODETYPE nt = NT_DD; gridnodes* gn = NULL; poly* pl = NULL; parse_commandline(argc, argv, &fname, &compact, &ij, &nt); if (nt == NT_DD) { /* * read DD grid nodes */ gridnodes* gndd = gridnodes_read(fname, NT_DD); gridnodes_validate(gndd); /* * get corner grid nodes from DD grid nodes */ gn = gridnodes_transform(gndd, NT_COR); gridnodes_destroy(gndd); } else { gn = gridnodes_read(fname, NT_COR); gridnodes_validate(gn); } /* * build boundary polygon */ if (!ij) pl = poly_formbound(gridnodes_getnce1(gn), gridnodes_getnce2(gn), gridnodes_getx(gn), gridnodes_gety(gn)); else pl = poly_formboundij(gridnodes_getnce1(gn), gridnodes_getnce2(gn), gridnodes_getx(gn)); if (compact) poly_compact(pl, 1.0e-10); poly_write(pl, stdout); poly_destroy(pl); gridnodes_destroy(gn); return 0; }
int sporth_poly(sporth_stack *stack, void *ud) { plumber_data *pd = ud; sporth_poly_d *poly; poly_voice *voice; poly_event *evt; uint32_t nvoices; char *ftname; char *file; uint32_t n, p; int id; switch(pd->mode) { case PLUMBER_CREATE: #ifdef DEBUG_MODE fprintf(stderr, "poly: Creating\n"); #endif poly = malloc(sizeof(sporth_poly_d)); plumber_add_ugen(pd, SPORTH_POLY, poly); if(sporth_check_args(stack, "ffss") != SPORTH_OK) { fprintf(stderr,"Invalid arguments for poly\n"); stack->error++; return PLUMBER_NOTOK; } ftname = sporth_stack_pop_string(stack); file = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); poly->dur = malloc(sizeof(uint32_t) * poly->max_voices); poly_init(&poly->poly); if(poly_binary_parse(&poly->poly, file, pd->sp->sr) != 0) { fprintf(stderr, "Could not read file %s\n", file); stack->error++; return PLUMBER_NOTOK; } poly_end(&poly->poly); poly_cluster_init(&poly->clust, poly->max_voices); sp_ftbl_create(pd->sp, &poly->ft, 1 + poly->max_voices * (2 + poly->max_params)); memset(poly->ft->tbl, 0, poly->ft->size * sizeof(SPFLOAT)); poly->ft->tbl[0] = poly->max_params; plumber_ftmap_add(pd, ftname, poly->ft); free(ftname); free(file); break; case PLUMBER_INIT: #ifdef DEBUG_MODE fprintf(stderr, "poly: Initialising\n"); #endif ftname = sporth_stack_pop_string(stack); file = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); free(ftname); free(file); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); sporth_stack_pop_float(stack); poly = pd->last->ud; poly_compute(&poly->poly); for(n = 0; n < poly->max_voices; n++) { poly->ft->tbl[1 + n * (poly->max_params + 2)] = 0.0; } poly_itr_reset(&poly->poly); for(n = 0; n < poly_nevents(&poly->poly); n++) { evt = poly_itr_next(&poly->poly); if(!poly_cluster_add(&poly->clust, &id)) { poly->dur[id] = evt->p[0] * pd->sp->sr; poly->ft->tbl[1 + id * (poly->max_params + 2)] = 1.0; poly->ft->tbl[2 + id * (poly->max_params + 2)] = evt->p[0]; for(p = 1; p < evt->nvals; p++) { poly->ft->tbl[2 + id * (poly->max_params + 2) + p] = evt->p[p]; } } } poly_cluster_reset(&poly->clust); nvoices = poly_cluster_nvoices(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); poly->dur[voice->val] -= 1; } poly_cluster_reset(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); if(poly->dur[voice->val] <= 0) { poly_cluster_remove(&poly->clust, voice->val); } } break; case PLUMBER_DESTROY: poly = pd->last->ud; poly_cluster_destroy(&poly->clust); poly_destroy(&poly->poly); free(poly->dur); free(poly); break; default: fprintf(stderr, "poly: Uknown mode!\n"); break; } return PLUMBER_OK; }