Пример #1
0
/* calculates the control points for a spline segment */
void get_control_points_backward(NODE n1, NODE n2, int points[8])
{
   fixed dist = fixmul(node_dist(n1, n2), curviness);

   points[0] = n1.x;
   points[1] = n1.y;

   points[2] = n1.x - fixtoi(fixmul(fixcos(n1.tangent), dist));
   points[3] = n1.y - fixtoi(fixmul(fixsin(n1.tangent), dist));

   points[4] = n2.x + fixtoi(fixmul(fixcos(n2.tangent), dist));
   points[5] = n2.y + fixtoi(fixmul(fixsin(n2.tangent), dist));

   points[6] = n2.x;
   points[7] = n2.y;
}
Пример #2
0
/* moves a sprite along the spline path */
void walk(void)
{
   #define MAX_POINTS    256

   int points[8];
   int x[MAX_POINTS], y[MAX_POINTS];
   int n, i;
   int npoints;
   int ox, oy;

   acquire_screen();

   clear_to_color(screen, makecol(255, 255, 255));

   for (i=1; i<node_count-1; i++)
      draw_node(i);

   release_screen();

   do {
      poll_mouse();
   } while (mouse_b);

   clear_keybuf();

   ox = -16;
   oy = -16;

   xor_mode(TRUE);

   for (n=1; n < node_count-2; n++) {
      npoints = (fixtoi(node_dist(nodes[n], nodes[n+1]))+3) / 4;
      if (npoints < 1)
	 npoints = 1;
      else if (npoints > MAX_POINTS)
	 npoints = MAX_POINTS;

      get_control_points(nodes[n], nodes[n+1], points);
      calc_spline(points, npoints, x, y);

      for (i=1; i<npoints; i++) {
	 vsync();
	 acquire_screen();
	 circlefill(screen, ox, oy, 6, palette_color[2]);
	 circlefill(screen, x[i], y[i], 6, palette_color[2]);
	 release_screen();
	 ox = x[i];
	 oy = y[i];

	 poll_mouse();

	 if ((keypressed()) || (mouse_b))
	    goto getout;
      }
   }

   getout:

   xor_mode(FALSE);

   do {
      poll_mouse();
   } while (mouse_b);

   clear_keybuf();
}
Пример #3
0
/*
 * Single source shortest path algorithm (Dijkstra's algorithm).
 */
static int shortest_path(double *nodeArray, int num_nodes, double *edgeArray, int num_edges,
			 int start_index, double dimdist[3], double radius, double *lastNodeList, int geoflag)
{
  int		i, cnt, num_nbhrs, curNodeIdx, curNhbrIdx, firstNodeOffset;
  double	*node, *new_node, *nbhrs, *nbhrdists, new_dist;
  PQueue	*PQ;

  /* Initialize distance to HUGE_VAL. */
  for (i=0, node=&nodeArray[DIST]; i<num_nodes; 
       i++, node+=NUM_ATTRS) *node = HUGE_VAL;

  /* Allocate priority queue and insert start_index as first node. */
  PQ = make_pqueue(num_nodes);
  node = NODEN(nodeArray,start_index-1);
  node[DIST] = 0.0;
  if (lastNodeList != NULL) {
    lastNodeList[start_index-1] = 0;
  }
  pqueue_insert(PQ, (PQueueNode)node);
  
  firstNodeOffset = ((int)NODEN(nodeArray,0));

  /* Dijkstra's algorithm. */
  cnt = 0;
  while (!pqueue_empty_p(PQ)) {
    node = (double *) pqueue_extract_min(PQ);
    curNodeIdx = (int)(((int)(node) - firstNodeOffset) / (8*NUM_ATTRS)) + 1;
    node[DIST] = -node[DIST]; 		/* computed */ 
    cnt++;
    
    /* Relax all the neighboring nodes. */
    num_nbhrs = (int) node[NUM_NBHRS];

    /* Get the geodesic distances to the neighbors. */
    if (geoflag == 1) {
      nbhrs = EDGEN(edgeArray,(((int)node[NBHRS])-1));
      nbhrdists = EDGEN(edgeArray,(((int)node[NBHRS])-1)) + 1;
    } else {
      nbhrs = &edgeArray[((int)node[NBHRS])-1];
    }

    for (i=0; i<num_nbhrs; i++) {
      if (geoflag == 1) {
        curNhbrIdx = ((int)nbhrs[2*i]);
        new_node = NODEN(nodeArray,((int)nbhrs[2*i])-1);
      } else {
        curNhbrIdx = (((int)nbhrs[i]));
        new_node = NODEN(nodeArray,((int)nbhrs[i])-1);
      }
      if (new_node[DIST]>=0) {	/* not computed yet */
	/* node[DIST] has been negated a couple of lines above.
	 * so, we need to negate it again to get the actual
	 * (positive) distance. 
	 * -node[DIST] is the distance from our working node
	 * to the start point.  node_dist() is the distance
	 * between our working node and its ith neighbor. */
        /* 08.05.98 SJC
 	 * If geoflag == 1, use the geodesic edge distance. */
        if (geoflag == 1) {
          new_dist = -node[DIST] + nbhrdists[2*i];
        } else {
  	  new_dist = -node[DIST] + node_dist(node, new_node, dimdist);
        }

	if (new_dist<radius) {
	  /* If this is the first time that we've gotten here, we
	   * use this new distance and add the node into the
	   * priority queue. */
	  if (new_node[DIST]==HUGE_VAL) {
	    new_node[DIST] = new_dist;
            if (lastNodeList != NULL) {
              lastNodeList[curNhbrIdx - 1] = curNodeIdx;
            }
	    pqueue_insert(PQ, (PQueueNode)new_node);
	  } 
	  /* Otherwise, if the new distance is less than
	   * the previously computed distance, then we pick
	   * the new (shorter) distance and adjust its
	   * position in the priority queue. */
	  else {
	    if (new_dist<new_node[DIST]) {
	      new_node[DIST] = new_dist;
              if (lastNodeList != NULL) {
		lastNodeList[curNhbrIdx - 1] = curNodeIdx;
              }
	      pqueue_deckey(PQ, (PQueueNode)new_node);
	    }
	  }
	}
      }
    }
  }
  free_pqueue(PQ);

  return(cnt);
}