int clip_line(struct liang_barsky_clip_window *c,
		float *x1, float *y1, float *x2,  float *y2)
{
	float dx, dy, tE, tL;

	dx = *x2 - *x1;
	dy = *y2 - *y1;

	if (is_zero(dx) && is_zero(dy) && point_inside(c, *x1, *y1))
		return 1;

	tE = 0;
	tL = 1;

	if (clipT(c->x1 - *x1,  dx, &tE, &tL) &&
		clipT( *x1 - c->x2, -dx, &tE, &tL) &&
		clipT(c->y1 - *y1,  dy, &tE, &tL) &&
		clipT( *y1 - c->y2, -dy, &tE, &tL)) {
		if (tL < 1) {
			*x2 = ((float) *x1 + tL * dx);
			*y2 = ((float) *y1 + tL * dy);
		}
		if (tE > 0) {
			*x1 += tE * dx;
			*y1 += tE * dy;
		}
		return 1;
	}
	return 0;
}
예제 #2
0
파일: sph.c 프로젝트: KonstantinosKr/solfec
/* does this sphere contain the point? */
int SPHERE_Contains_Point (void *dummy, SPHERE *sph, double *point)
{
  return point_inside (sph->cur_center, sph->cur_radius, point);
}
예제 #3
0
파일: sph.c 프로젝트: KonstantinosKr/solfec
/* return sphere containing a spatial point */
SPHERE* SPHERE_Containing_Point (SPHERE *sph, double *point)
{
  if (point_inside (sph->cur_center, sph->cur_radius, point)) return sph;
  else return NULL;
}
예제 #4
0
파일: quadtree.c 프로젝트: jsvana/quadtree
static int quadtree_insert_node(quadtree *q, quadtree_node *qn, void *data,
		size_t size, double x, double y) {
	if (!qn) {
		return QUADTREE_ERROR;
	}

	if (!quadtree_node_has_children(qn) && llist_is_empty(qn->points)) {
		quadtree_data *qd = quadtree_data_create(data, size, x, y);
		if (!qd) {
			return QUADTREE_ERROR;
		}
		llist_add_to_back(qn->points, qd, sizeof(quadtree_data));
		free(qd);
		++q->size;

		return QUADTREE_OK;
	} else {
		quadtree_data *d = llist_first(qn->points);
		if (d && quadtree_data_same_location(d, x, y)) { // Same point
			quadtree_data *qd = quadtree_data_create(data, size, x, y);
			if (!qd) {
				return QUADTREE_ERROR;
			}
			llist_add_to_back(qn->points, qd, sizeof(quadtree_data));
			free(qd);
			return QUADTREE_OK;
		} else {
			quadtree_data *e = llist_first(qn->points);
			// Split node
			double minX = qn->bounds.x;
			double minY = qn->bounds.y;
			double midX = qn->bounds.x + qn->bounds.w / 2;
			double midY = qn->bounds.y + qn->bounds.h / 2;
			double maxX = qn->bounds.x + qn->bounds.w;
			double maxY = qn->bounds.y + qn->bounds.h;
			double xDim[4][2] = {
				{ midX, maxX - midX },
				{ minX, midX - minX },
				{ minX, midX - minX },
				{ midX, maxX - midX }
			};
			double yDim[4][2] = {
				{ midY, maxY - midY },
				{ midY, maxY - midY },
				{ minY, midY - minY },
				{ minY, midY - minY }
			};

			quadtree_data *d = llist_first(qn->points);

			int ret = QUADTREE_ERROR;

			for (int i = 0; i < 4; i++) {
				if (point_inside(xDim[i][0], yDim[i][0], xDim[i][1], yDim[i][1], x, y)
						|| (d && point_inside(xDim[i][0], yDim[i][0], xDim[i][1], yDim[i][1],
							d->x, d->y))) {
					if (!qn->children[i]) {
						qn->children[i] = quadtree_node_create();
					}
						quadtree_node_set_bounds(qn->children[i], xDim[i][0], yDim[i][0],
							xDim[i][1], yDim[i][1]);
						if (point_inside(xDim[i][0], yDim[i][0], xDim[i][1], yDim[i][1], x,
								y)) {
							quadtree_insert_node(q, qn->children[i], data, size, x, y);
							ret = QUADTREE_OK;
						} else if (point_inside(xDim[i][0], yDim[i][0], xDim[i][1],
								yDim[i][1], d->x, d->y)) {
							// Move contained points into child node
							qn->children[i]->points = qn->points;
							qn->points = NULL;
							ret = QUADTREE_OK;
						}
				}
			}
			return ret;
		}
	}

	// Shouldn't happen
	return QUADTREE_ERROR;
}
예제 #5
0
파일: clip3d.c 프로젝트: Skiles/aseprite
/* clip3d:
 *  A fixed point version of clip3d_f. Works suprisingly well.
 */
int clip3d(int type, fixed min_z, fixed max_z, int vc, AL_CONST V3D *vtx[], V3D *vout[], V3D *vtmp[], int out[])
{
   int i, j, vo, vt, flags;
   fixed t;
   V3D *v3;

   AL_CONST V3D *v1, *v2, **vin;

   static int flag_table[] = {
      INT_NONE,                             /* flat */
      INT_3COLP,                            /* gcol */
      INT_3COL,                             /* grgb */
      INT_UV,                               /* atex */
      INT_UV,                               /* ptex */
      INT_UV,                               /* atex mask */
      INT_UV,                               /* ptex mask */
      INT_UV + INT_1COL,                    /* atex lit */
      INT_UV + INT_1COL,                    /* ptex lit */
      INT_UV + INT_1COL,                    /* atex mask lit */
      INT_UV + INT_1COL,                    /* ptex mask lit */
      INT_UV,                               /* atex trans */
      INT_UV,                               /* ptex trans */
      INT_UV,                               /* atex mask trans */
      INT_UV                                /* ptex mask trans */
   };

   type &= ~POLYTYPE_ZBUF;
   flags = flag_table[type];

   if (max_z > min_z) {
      vt = 0;

      for (i=0; i<vc; i++)
	 out[i] = (vtx[i]->z > max_z);

      for (i=0, j=vc-1; i<vc; j=i, i++) {
	 v1 = vtx[j];
	 v2 = vtx[i];
	 v3 = vtmp[vt];

	 if ((out[j] & out[i]) != 0)
	    continue;

	 if ((out[j] | out[i]) == 0) {
	    point_inside(vt);
	    continue;
	 }

	 t = fixdiv(max_z - v1->z, v2->z - v1->z);
	 point_interp(vt);
	 v3 = vtmp[vt];

	 if (out[j])
	    point_inside(vt);
      }
      vin = (AL_CONST V3D**)vtmp;
   }
   else {
      vt = vc;
      vin = vtx;
   }

   vo = 0;

   for (i=0; i<vt; i++)
      out[i] = (vin[i]->z < min_z);

   for (i=0, j=vt-1; i<vt; j=i, i++) {
      v1 = vin[j];
      v2 = vin[i];
      v3 = vout[vo];

      if ((out[j] & out[i]) != 0)
	 continue;

      if ((out[j] | out[i]) == 0) {
	 point_inside(vo);
	 continue;
      }

      t = fixdiv(min_z - v1->z, v2->z - v1->z);
      point_interp(vo);
      v3 = vout[vo];

      if (out[j])
	 point_inside(vo);
   }

   vt = 0;

   for (i=0; i<vo; i++)
      out[i] = (vout[i]->x < -vout[i]->z);

   for (i=0, j=vo-1; i<vo; j=i, i++) {
      v1 = vout[j];
      v2 = vout[i];
      v3 = vtmp[vt];

      if ((out[j] & out[i]) != 0)
	 continue;

      if ((out[j] | out[i]) == 0) {
	 point_inside(vt);
	 continue;
      }

      t = fixdiv(-v1->z - v1->x, v2->x - v1->x + v2->z - v1->z);
      point_interp(vt);
      v3 = vtmp[vt];

      if (out[j])
	 point_inside(vt);
   }

   vo = 0;

   for (i=0; i<vt; i++)
      out[i] = (vtmp[i]->x > vtmp[i]->z);

   for (i=0, j=vt-1; i<vt; j=i, i++) {
      v1 = vtmp[j];
      v2 = vtmp[i];
      v3 = vout[vo];

      if ((out[j] & out[i]) != 0)
	 continue;

      if ((out[j] | out[i]) == 0) {
	 point_inside(vo);
	 continue;
      }

      t = fixdiv(v1->z - v1->x, v2->x - v1->x - v2->z + v1->z);
      point_interp(vo);
      v3 = vout[vo];

      if (out[j])
	 point_inside(vo);
   }

   vt = 0;

   for (i=0; i<vo; i++)
      out[i] = (vout[i]->y < -vout[i]->z);

   for (i=0, j=vo-1; i<vo; j=i, i++) {
      v1 = vout[j];
      v2 = vout[i];
      v3 = vtmp[vt];

      if ((out[j] & out[i]) != 0)
	 continue;

      if ((out[j] | out[i]) == 0) {
	 point_inside(vt);
	 continue;
      }

      t = fixdiv(-v1->z - v1->y, v2->y - v1->y + v2->z - v1->z);
      point_interp(vt);
      v3 = vtmp[vt];

      if (out[j])
	 point_inside(vt);
   }

   vo = 0;

   for (i=0; i<vt; i++)
      out[i] = (vtmp[i]->y > vtmp[i]->z);

   for (i=0, j=vt-1; i<vt; j=i, i++) {
      v1 = vtmp[j];
      v2 = vtmp[i];
      v3 = vout[vo];

      if ((out[j] & out[i]) != 0)
	 continue;

      if ((out[j] | out[i]) == 0) {
	 point_inside(vo);
	 continue;
      }

      t = fixdiv(v1->z - v1->y, v2->y - v1->y - v2->z + v1->z);
      point_interp(vo);
      v3 = vout[vo];

      if (out[j])
	 point_inside(vo);
   }

   if (type == POLYTYPE_FLAT)
      vout[0]->c = vtx[0]->c;

   return vo;
}
예제 #6
0
/** for a pair (p, q) of points, add the edge pq if their are visible to each other
*/
void handle(struct Point *p, struct Point *q, struct Map_info *out)
{

    /* if it's a point without segments, just report the edge */
    if (segment1(q) == NULL && segment2(q) == NULL && before(p, q, p->vis)) {
	report(p, q, out);
    }
    else if (segment1(p) != NULL && q == other1(p)) {
	/* we need to check if there is another segment at q so it can be set to the vis */
	if (segment1(q) == segment1(p) && segment2(q) != NULL &&
	    left_turn(p, q, other2(q))) {
	    p->vis = segment2(q);
	}
	else if (segment2(q) == segment1(p) && segment1(q) != NULL &&
		 left_turn(p, q, other1(q))) {
	    p->vis = segment1(q);
	}
	else
	    p->vis = q->vis;

	report(p, q, out);
    }
    else if (segment2(p) != NULL && q == other2(p)) {
	/* we need to check if there is another segment at q so it can be set to the vis */
	if (segment1(q) == segment2(p) && segment2(q) != NULL &&
	    left_turn(p, q, other2(q))) {
	    p->vis = segment2(q);
	}
	else if (segment2(q) == segment2(p) && segment1(q) != NULL &&
		 left_turn(p, q, other1(q))) {
	    p->vis = segment1(q);
	}
	else
	    p->vis = q->vis;

	report(p, q, out);
    }
    else if (segment1(q) == p->vis && segment1(q) != NULL) {
	/* we need to check if there is another segment at q so it can be set to the vis */
	if (segment2(q) != NULL && left_turn(p, q, other2(q)))
	    p->vis = segment2(q);
	else
	    p->vis = q->vis;

	/* check that p and q are not on the same boundary and that the edge pq is inside the boundary */
	if (p->cat == -1 || p->cat != q->cat ||
	    !point_inside(p, (p->x + q->x) * 0.5, (p->y + q->y) * 0.5))
	    report(p, q, out);
    }
    else if (segment2(q) == p->vis && segment2(q) != NULL) {
	/* we need to check if there is another segment at q so it can be set to the vis */
	if (segment1(q) != NULL && left_turn(p, q, other1(q)))
	    p->vis = segment1(q);
	else
	    p->vis = q->vis;

	/* check that p and q are not on the same boundary and that the edge pq is inside the boundary */
	if (p->cat == -1 || p->cat != q->cat ||
	    !point_inside(p, (p->x + q->x) * 0.5, (p->y + q->y) * 0.5))
	    report(p, q, out);
    }
    else if (before(p, q, p->vis)) {
	/* if q only has one segment, then this is the new vis */
	if (segment2(q) == NULL)
	    p->vis = segment1(q);
	else if (segment1(q) == NULL)
	    p->vis = segment2(q);

	/* otherwise take the one with biggest slope */
	else if (left_turn(p, q, other1(q)) && !left_turn(p, q, other2(q)))
	    p->vis = segment1(q);
	else if (!left_turn(p, q, other1(q)) && left_turn(p, q, other2(q)))
	    p->vis = segment2(q);
	else if (left_turn(q, other2(q), other1(q)))
	    p->vis = segment1(q);
	else
	    p->vis = segment2(q);

	/* check that p and q are not on the same boundary and that the edge pq is inside the boundary */
	if (p->cat == -1 || p->cat != q->cat ||
	    !point_inside(p, (p->x + q->x) * 0.5, (p->y + q->y) * 0.5))
	    report(p, q, out);
    }
}