home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
virtualTours.c
< prev
Wrap
C/C++ Source or Header
|
1996-05-30
|
8KB
|
311 lines
/*************************************************************************
Christopher Jaynes
Feb 6, 1995
U.Mass RADIUS project
virtualTours
After all of the feature tours (polygon hypotheses) have been detected,
search for tours that can be completed with a single missing feature
ie- nodes separated by 1 relation in the Feature Relation Graph.
Generate a virtual feature, check for support in the image, and
add it to the graph.
***************************************************************************/
#include "../polygons.h"
#define WHITE 1
#define GREY 2
#define BLACK 3
#define RED 4
#define BLUE 5
#define T 2
#define L 3
int virtualSelf_intersect(vertexList *p, cList *virtual,cList *e1, cList *e2);
cList *createVirtualFeature(cList *first, cList *next,Point p, double weight);
void virtualTours(c_handle im, cList *v_list, int *curr_color,
MGvertex **meta_graph)
/*
* Once all of the tours have been detected in the Feature Relation
* Graph. Perform a tour search again, this time, attempt to generate
* virtual features between existing node that will complete cycles.
*
* Virtual features cannot be generated between nodes that are both
* in the same cycle.
*
*/
{
vertexList *back_list;
cList *nodes;
back_list=NULL;
nodes=v_list;
while (nodes != NULL)
{
*curr_color=virtualTour(im,nodes,AXIS1,*curr_color,&back_list,
&v_list,meta_graph,0);
nodes=nodes->next;
}
}
int virtualTour(c_handle im, cList *list, int axis, int color, vertexList **visited_list, cList **graph, MGvertex **meta_graph, int depth)
{
edgeList *edges;
int current_color;
vertexList *hb;
vertexList *cycle_list;
vertexList *Vptr;
vertexList *tempPtr;
vertexList *first; /** List pointer for the visited lsit **/
MGvertex *hmv;
double mag;
double weight, weight1, weight2;
int virtualFeature=FALSE;
double height;
Point gPoint;
colorList *ptr;
vertexList *pt;
int fDepth;
int dir;
cList *vNode;
int i;
if (color > MAX_ALLOWED_COLOR)
{
fprintf(stderr,"max color reached, search aborted incomplete \n");
return(color);
}
edges=list->eList;
current_color=color;
/*** Changed to disallow search depth greater than MAXCHAINLEN **/
while (edges != NULL && depth <= MAXCHAINLEN)
{
/* Follow a different axis out of the current node **/
if (edges->type != axis) {
if (!in_visited_list(*visited_list,edges->vertex) &&
!self_intersect(*visited_list,edges->vertex)) {
hb=(vertexList *)malloc(sizeof(vertexList));
hb->next = *visited_list;
hb->vertex = list;
hb->confidence = edges->confidence;
hb->vertex->depth = depth;
*visited_list = hb;
fDepth = depth+1;
if ((fDepth > 1) && !(fDepth % 2)) {
first = *visited_list; /* Set first node in visited list */
while (first->next != NULL){
first = first->next;
}
/** The first and last nodes must be at least 1
node apart for virtual feature production. Also,
the current node cannot take part in a virtual cycle. **/
if ( ((fDepth - first->vertex->depth > 1) &&
(edges->vertex->P != TRUE || first->vertex->P != TRUE)) ) {
if (!K_CYCLES || ((edges->vertex->P != TRUE) &&
first->vertex->P != TRUE)) {
gPoint = TfeatureGap(edges->vertex,edges->type,first->vertex);
if (goodFeature(gPoint) ) {
/** Valid corner, now see if there is enough
image support/
if ( (weight1 =virtualTokenSupport(gPoint,edges->vertex)) &&
(weight2 =virtualTokenSupport(gPoint,first->vertex))) {
weight = weight1+weight2;
virtualFeature=TRUE;
} else **/
if ( (weight =
virtualSupport(im,&gPoint,edges->vertex, edges->type,
first->vertex,&dir))) {
virtualFeature = TRUE;
}
else {
virtualFeature = FALSE;
}
if (virtualFeature) {
vNode = createVirtualFeature(first->vertex,
edges->vertex, gPoint,0.0);
if (virtualSelf_intersect(*visited_list, vNode,
edges->vertex,first->vertex)){
free(vNode);
}
else { /* Good feature, add this polygon */
vNode->next = *graph;
*graph = vNode;
cycle_list = NULL; mag = 0.0;
add_color(&(edges->vertex->colors),current_color);
add_color(&(list->colors),current_color);
add_color(&(vNode->colors),current_color);
insert_vertex_into_polygon(vNode,&cycle_list);
insert_vertex_into_polygon(edges->vertex,&cycle_list);
/* insert_vertex_into_polygon(list,&cycle_list);
*/
color_all(*visited_list,NULL,&cycle_list,
current_color,&mag,TRUE);
hmv=(MGvertex *)malloc(sizeof(MGvertex));
hmv->vList = cycle_list;
hmv->eList = NULL;
hmv->next = *meta_graph;
hmv->color = current_color;
hmv->isscolor = WHITE;
hmv->confidence = mag + edges->vertex->magnitude
+ edges->confidence
+ list->magnitude
+ vNode->magnitude;
*meta_graph = hmv;
current_color++;
} /* No self intersection */
} /* Enough Support */
} /* Good Feature (in boundaries) */
}
} /* Deep enough, vertex not already in polygon */
} /* Valid even depth */
current_color = virtualTour(im, edges->vertex, edges->type,
current_color,visited_list,graph,meta_graph,
depth+1);
(*visited_list) = (*visited_list)->next;
free(hb);
} /** In visited list **/
} /** Correct Axis **/
edges = edges->next;
} /* While */
return(current_color);
}
int virtualSelf_intersect(vertexList *p, cList *v, cList *end1, cList *end2)
/*
*
* Return TRUE if there is an intersection between the new virtual
* feature and any of the other lines between nodes in the visited
* list.
* Return FALSE otherwise.
*
*/
{
line l;
line testLine;
double Parms[2];
double_2 Ipoint;
vertexList *ptr;
double_2 *res;
double angleError = 3.13;
if (p == NULL)
return(FALSE);
/* Make a line between the vertex 'virtual' and the last visited
node. Check to see if this line intersects any other
line in the path */
l.x1 = v->x; l.y1 = v->y;
l.x2 = end1->x; l.y2 = end1->y;
/** Move through all other possible lines **/
ptr = p;
while (ptr->next != NULL && ptr->vertex != NULL) {
testLine.x1 = ptr->vertex->x; testLine.y1 = ptr->vertex->y;
testLine.x2 = ptr->next->vertex->x;
testLine.y2 = ptr->next->vertex->y;
intersect_point(l,testLine,&Ipoint);
computeParms(Ipoint,l,testLine,Parms);
if (Parms[0] > 0.0 && Parms[0] < 1.0 && Parms[1] > 0.0
&& Parms[1] < 1.0) {
return(TRUE);
}
ptr = ptr->next;
}
l.x1 = v->x; l.y1 = v->y;
l.x2 = end2->x; l.y2 = end2->y;
ptr = p;
while (ptr->next != NULL && ptr->vertex != NULL) {
testLine.x1 = ptr->vertex->x; testLine.y1 = ptr->vertex->y;
testLine.x2 = ptr->next->vertex->x;
testLine.y2 = ptr->next->vertex->y;
intersect_point(l,testLine,&Ipoint);
computeParms(Ipoint,l,testLine,Parms);
if (Parms[0] > 0.0 && Parms[0] < 1.0 && Parms[1] > 0.0
&& Parms[1] < 1.0) {
free(res);
return(TRUE);
}
ptr = ptr->next;
}
return(FALSE);
}
cList *createVirtualFeature(cList *first, cList *next,Point p, double weight)
{
cList *v;
v = (cList *) malloc( sizeof(cList));
v->x = (int) p.x;
v->y = (int) p.y;
v->height = (first->height + next->height)/2.0;
v->magnitude = weight;
v->colors = NULL;
v->next = NULL;
return(v);
}
int goodFeature(Point p)
{
if ( (p.x > xstart && p.y > ystart && p.x < xstop && p.y < ystop) &&
p.z != NONE)
return(TRUE);
return(FALSE);
}