⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rebuild.c

📁 source code to compute the visibility polygon of a point in a polygon.
💻 C
字号:
/* rebuild.C  * Brian O'Connor * * Functions to build a new environment given the original one. * The new environment will be the old environment minus the area  * that the original pursuer was able to search in that environment. */#include <stdio.h>#include <assert.h>#include "input.h"#include "line.h"#include "cell.h"#include "rebuild.h"#include "pursuer.h"#include "pgraph.h"#include "vispoly.h"Line *FindDirtyBorder(PInfo *pinfo);Line *FindDirtyEdge(PInfo *pinfo, Point *p);int GapEdgeIntersection(PInfo *pinfo, Line *last, Line **next);Line *FindNextEdge(PInfo *pinfo, Line *last, Point *p);Line *DirtyEdgeSegment(PInfo *pinfo, Line *edge, Point *p);Line *DirtyCorner(PInfo *pinfo, int hit1, int hit2, Point *p);void  AddUniquePt(Obstacle *border, Line *next);int  TestClosure(Line *next, Obstacle *border);/* starting from a dirty gap edge in the old environment, traverse the  * edges until we make a loop in the new environment. */int RebuildInput(PInfo *pinfo, WorldInfo *wInfo){  Line *start;  Line *next;  Line *last;  int bGap;  wInfo->nObs = 0;  wInfo->robot = NULL;  wInfo->obs = new (Obstacle *);  wInfo->obs[0] = NULL;  wInfo->border = new Obstacle;  wInfo->border->pts = new Point[100];  wInfo->border->nPts = 0;  next = NULL;  bGap = TRUE;  start = FindDirtyBorder(pinfo);  last = start;  wInfo->border->pts[wInfo->border->nPts++] = *last->B;  wInfo->border->pts[wInfo->border->nPts++] = *last->A;  while( next != start ) {    if( bGap ) {      next = FindDirtyEdge(pinfo, last->A);      if( TestClosure(next, wInfo->border) ) {	return(TRUE);      }      AddUniquePt(wInfo->border, next);      bGap = FALSE;    } else {      if( !GapEdgeIntersection(pinfo, last, &next) ) {	next = FindNextEdge(pinfo, last,			    &wInfo->border->pts[wInfo->border->nPts - 1]);	if( TestClosure(next, wInfo->border) ) {	  return(TRUE);	}	AddUniquePt(wInfo->border, next);	bGap = FALSE;      } else {	// change our last endpont and set the new endpoint.	if( PointOnSegment(last, next->A)) {	  wInfo->border->pts[wInfo->border->nPts-1] = *next->A;	  wInfo->border->pts[wInfo->border->nPts++] = *next->B;	} else {	  assert( PointOnSegment(last, next->B) );	  wInfo->border->pts[wInfo->border->nPts-1] = *next->B;	  wInfo->border->pts[wInfo->border->nPts++] = *next->A;	  	}	bGap = TRUE;      }    }        last = next;  }    return(TRUE);}/* iterate through the 'best' vpoly we found in this pinfo and select a  * dirty gap edge; this will be the starting edge for the new environment. */Line *FindDirtyBorder(PInfo *pinfo){  VPoly *vpoly;  int i, gapNum;  gapNum = 0;  vpoly = pinfo->pg->Best()->NodeCell()->vPoly;  // clear marks since we need to use them again  for( i = 0; i < vpoly->nEdges; i++ ) {    if( vpoly->edges[i]->bGap ) {      vpoly->edges[i]->bMark = FALSE;    }  }  for( i = 0; i < vpoly->nEdges; i++ ) {    if( vpoly->edges[i]->bGap ) {      if( pinfo->pg->Best()->NodeState() & ( 1 << gapNum ) ) {	vpoly->edges[i]->bMark = TRUE;	return( vpoly->edges[i] );      }      gapNum++;    }  }  assert(0); // there should always be 1 dirty gap edge in the vpoly}/* p will be a pt on a gap edge; find the edge it is a part of and return   the portion of that edge that was not covered by the vispoly we    have in pinfo.   */Line *FindDirtyEdge(PInfo *pinfo, Point *p){  EdgeInfo *e;  int i;  int nHits, hits[2];  e = pinfo->edgeInfo;  nHits = 0;  for( i = 0; i < e->nEdges; i++ ) {    if( PointOnSegment(e->edges[i], p)) {      hits[nHits++] = i;    }  }  assert( nHits > 0 );  if( nHits == 1 ) {    return( DirtyEdgeSegment(pinfo, e->edges[hits[0]], p));  } else {    assert( nHits == 2 );    return( DirtyCorner(pinfo, hits[0], hits[1], p) );  }}/* split edge at p; one part was in the old vpoly and we want to return   the other part. */Line *DirtyEdgeSegment(PInfo *pinfo, Line *edge, Point *p){  int i;  VPoly *vpoly;  Point *p1, *p2;  p1 = new Point;  p2 = new Point;  vpoly = pinfo->pg->Best()->NodeCell()->vPoly;  for( i = 0; i < vpoly->nEdges; i++ ) {    if( LinesOverlap(edge, vpoly->edges[i], &p1, &p2) ) {      if( PointEqual(vpoly->edges[i]->A, p) ) {	p1 = vpoly->edges[i]->B;      } else if( PointEqual(vpoly->edges[i]->B, p)) {	p1 = vpoly->edges[i]->A;       } else continue;      if( LineDistance(p, edge->A) > LineDistance(p1, edge->A) ) {	// means vpoly is moving away from A	return new Line(p, edge->B);      } else {	return new Line(p, edge->A);      }    }  }  assert(0); // should have been an overlap somewhere  return(NULL);}/* p is the corner of 2 edges; one of these edges will be in vpoly and   we want to return the other edge. */Line *DirtyCorner(PInfo *pinfo, int hit1, int hit2, Point *p){  VPoly *vpoly;  int i;  Point *p1, *p2;  p1 = new Point;  p2 = new Point;  vpoly = pinfo->pg->Best()->NodeCell()->vPoly;  for( i = 0; i < vpoly->nEdges; i++ ) {    if( LinesOverlap(pinfo->edgeInfo->edges[hit1], vpoly->edges[i], &p1,		     &p2)) {      // hit1 is in the vpoly, so return hit2.      return( pinfo->edgeInfo->edges[hit2] );    } else if( LinesOverlap(pinfo->edgeInfo->edges[hit2], vpoly->edges[i],			    &p1, &p2)) {      // hit 2 is in the vpoly, so return hit1.      return( pinfo->edgeInfo->edges[hit1] );    }  }  assert(0); // should have found a hit}// check every gap edge in vpoly and see if one intersects last.int GapEdgeIntersection(PInfo *pinfo, Line *last, Line **next){  VPoly *vpoly;  int i;  vpoly = pinfo->pg->Best()->NodeCell()->vPoly;  for( i = 0; i < vpoly->nEdges; i++ ) {    if( vpoly->edges[i]->bGap && !vpoly->edges[i]->bMark &&	(PointOnSegment(last, vpoly->edges[i]->A) ||	PointOnSegment(last, vpoly->edges[i]->B)) ) {      // we found a gap edge intersecting this edge.      vpoly->edges[i]->bMark = TRUE;      *next = vpoly->edges[i];      return(TRUE);    }  }  return(FALSE);}/* given an edge from the original decomposition return the next edge   in A to B direction. */Line *FindNextEdge(PInfo *pinfo, Line *last, Point *p){  EdgeInfo *e;  int i;  e = pinfo->edgeInfo;  for( i = 0; i < e->nEdges; i++ ) {    if( PointOnSegment(e->edges[i], p) && e->edges[i] != last) {      return( e->edges[i] );    }  }  // should always find a match  assert(0);}/* one point on next should match the last point in the border; so add the   other point. */void  AddUniquePt(Obstacle *border, Line *next){  Point *p;  p = &border->pts[border->nPts - 1];  if( PointEqual(p, next->A) ) {    border->pts[border->nPts++] = *next->B;  } else {    assert( PointEqual(p, next->B) );    border->pts[border->nPts++] = *next->A;  }}/* if the line we just added was the last in the border, we need to add * the last point and exit. */int  TestClosure(Line *next, Obstacle *border){  if( PointOnSegment(next, &border->pts[0]) ) {    return(TRUE);  }  return(FALSE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -