/* find_longest_path: * Find and return longest path in tree. */ static nodelist_t* find_longest_path(Agraph_t* tree) { Agnode_t* n; Agedge_t* e; Agnode_t* common = 0; nodelist_t* path; nodelist_t* endPath; int maxlength = 0; int length; if (agnnodes(tree) == 1) { path = mkNodelist(); n = agfstnode(tree); appendNodelist(path, NULL, n); SET_ONPATH(n); return path; } for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { int count = 0; for(e = agfstedge(tree, n); e; e = agnxtedge(tree, e, n)) { count++; } if(count == 1) measure_distance(n, n, 0, NULL); } /* find the branch node rooted at the longest path */ for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { length = DISTONE(n) + DISTTWO(n); if(length > maxlength) { common = n; maxlength = length; } } path = mkNodelist(); for (n = LEAFONE(common); n != common; n = TPARENT(n)) { appendNodelist(path, NULL, n); SET_ONPATH(n); } appendNodelist(path, NULL, common); SET_ONPATH(common); if (DISTTWO(common)) { /* 2nd path might be empty */ endPath = mkNodelist(); for (n = LEAFTWO(common); n != common; n = TPARENT(n)) { appendNodelist(endPath, NULL, n); SET_ONPATH(n); } reverseAppend(path, endPath); } return path; }
static void measure_distance(Agnode_t * n, Agnode_t * ancestor, int dist, Agnode_t * change) { Agnode_t *parent; parent = TPARENT(ancestor); if (parent == NULL) return; dist++; /* check parent to see if it has other leaf paths at greater distance than the context node. set the path/distance of the leaf at this ancestor node */ if (DISTONE(parent) == 0) { LEAFONE(parent) = n; DISTONE(parent) = dist; } else if (dist > DISTONE(parent)) { if (LEAFONE(parent) != change) { if (!DISTTWO(parent) || (LEAFTWO(parent) != change)) change = LEAFONE(parent); LEAFTWO(parent) = LEAFONE(parent); DISTTWO(parent) = DISTONE(parent); } LEAFONE(parent) = n; DISTONE(parent) = dist; } else if (dist > DISTTWO(parent)) { LEAFTWO(parent) = n; DISTTWO(parent) = dist; return; } else return; measure_distance(n, parent, dist, change); }
void loop() { unsigned int current_distance = measure_distance(); Serial.println(current_distance); }
void zmat_build(void) { gint i, j, k, n, type; gdouble r, a, d, x[4][3], v[3]; gdouble zaxis[3] = {0.0, 0.0, 1.0}; gchar *line; GSList *list, *species; struct zmat_pak *zmat; struct core_pak *core[4] = {NULL, NULL, NULL, NULL}; struct model_pak *model; model = sysenv.active_model; if (!model) return; /* CURRENT - using selection as our list of cores to generate a zmatrix from */ if (!model->selection) { gui_text_show(WARNING, "ZMATRIX: please select a molecule.\n"); return; } /* destroy old zmatrix */ /* TODO - prompt if non null */ zmat_free(model->zmatrix); zmat = model->zmatrix = zmat_new(); zmat_angle_units_set(model->zmatrix, DEGREES); /* setup SIESTA species type */ species = fdf_species_build(model); /* sort the list so it follows molecular connectivity */ model->selection = zmat_connect_sort(model->selection); n=0; for (list=model->selection ; list ; list=g_slist_next(list)) { /* current atom/zmatrix line init */ core[0] = list->data; type = fdf_species_index(core[0]->atom_label, species); line = NULL; zmat->zcores = g_slist_append(zmat->zcores, core[0]); /* build a ZMATRIX line for processing */ switch (n) { case 0: if (core[0]) { ARR3SET(x[0], core[0]->x); vecmat(model->latmat, x[0]); } line = g_strdup_printf("%d 0 0 0 %f %f %f 0 0 0\n", type, x[0][0], x[0][1], x[0][2]); break; case 1: if (core[0]) { ARR3SET(x[0], core[0]->x); vecmat(model->latmat, x[0]); } if (core[1]) { ARR3SET(x[1], core[1]->x); vecmat(model->latmat, x[1]); } r = measure_distance(x[0], x[1]); /* angle with z axis */ ARR3SET(v, x[0]); ARR3SUB(v, x[1]); a = R2D * via(v, zaxis, 3); /* angle between xy projection and x axis */ d = R2D * angle_x_compute(v[0], v[1]); line = g_strdup_printf("%d 1 0 0 %f %f %f 0 0 0\n", type, r, a, d); break; case 2: /* coords init */ for (i=3 ; i-- ; ) { if (core[i]) { ARR3SET(x[i], core[i]->x); vecmat(model->latmat, x[i]); } else g_assert_not_reached(); } r = measure_distance(x[0], x[1]); a = measure_angle(x[0], x[1], x[2]); /* create a fake core -> 1 unit displaced in the z direction */ g_assert(core[3] == NULL); core[3] = core_new("x", NULL, model); ARR3SET(core[3]->rx, core[2]->rx); ARR3ADD(core[3]->rx, zaxis); d = measure_torsion(core); core_free(core[3]); line = g_strdup_printf("%d 2 1 0 %f %f %f 0 0 0\n", type,r,a,d); break; default: /* connectivity test */ if (!zmat_bond_check(core[0], core[1])) { #if DEBUG_ZMAT_BUILD printf("[%d] non-connected atoms [%f]\n", n, measure_distance(x[0], x[1])); #endif /* need to build a new connectivity chain starting from core[0] */ core[1] = core[2] = core[3] = NULL; if (!zmat_connect_find(n, core, zmat)) { gui_text_show(WARNING, "ZMATRIX: bad connectivity (molecule will be incomplete)\n"); goto zmat_build_done; } } /* coords init */ for (i=3 ; i-- ; ) { if (core[i]) { ARR3SET(x[i], core[i]->x); vecmat(model->latmat, x[i]); } else g_assert_not_reached(); } r = measure_distance(x[0], x[1]); a = measure_angle(x[0], x[1], x[2]); d = measure_torsion(core); /* NB: indexing starts from 0, siesta starts from 1 (naturally) */ i = 1+g_slist_index(zmat->zcores, core[1]); j = 1+g_slist_index(zmat->zcores, core[2]); k = 1+g_slist_index(zmat->zcores, core[3]); line = g_strdup_printf("%d %d %d %d %f %f %f 0 0 0\n", type,i,j,k,r,a,d); } /* process a successfully constructed ZMATRIX line */ if (line) { zmat_core_add(line, model->zmatrix); g_free(line); } /* shuffle */ core[3] = core[2]; core[2] = core[1]; core[1] = core[0]; n++; } zmat_build_done: /* do the species typing */ zmat_type(model->zmatrix, species); free_slist(species); }