Пример #1
0
/* Find the closest point in list to point p, return NULL if list empty */
int point_list_closest(struct point_list *l, struct point *p)
{
	assert(l != NULL);
	assert(p != NULL);
	
	int i;
	int length = point_list_length(l);
	double min_d, temp_d;
	int min_i;
   
	if (length <= 0)
		return -1;
		
	min_i = 0;
	min_d = point_distance(&(l->plist[0]), p);
		
	for (i = 1; i < length; i++) {
	    temp_d = point_distance(&(l->plist[i]), p);
	    if (temp_d < min_d) {
	        min_d = temp_d;
	        min_i = i;
	    }
	}	
	return min_i;
}
Пример #2
0
double *dist_ps(Point *pt, LSEG *lseg)
{
    double m;                       /* slope of perp. */
    LINE *ln;
    double *result, *tmpdist;
    Point *ip;
    
    /* construct a line that's perpendicular.  See if the intersection of
       the two lines is on the line segment. */
    if (lseg->p[1].x == lseg->p[0].x)
	m = 0;
    else if (lseg->p[1].y == lseg->p[0].y) /* slope is infinite */
	m = (double)DBL_MAX;
    else m = (-1) * (lseg->p[1].y - lseg->p[0].y) / 
	(lseg->p[1].x - lseg->p[0].x);
    ln = line_construct_pm(pt, m);
    
    if ((ip = interpt_sl(lseg, ln)) != NULL)
	result = point_distance(pt, ip);
    else  /* intersection is not on line segment, so distance is min
	     of distance from point to an endpoint */
	{
	    result = point_distance(pt, &lseg->p[0]);
	    tmpdist = point_distance(pt, &lseg->p[1]);
	    if (*tmpdist < *result) *result = *tmpdist;
	    PFREE (tmpdist);
	}
    
    if (ip != NULL) PFREE(ip);
    PFREE(ln);
    return (result);
}
Пример #3
0
int main(int argc, char **argv)
{
  Point p1;
  Point *p2 = malloc(sizeof(Point));
  assert(p2);
  double distance;
  
  point_set(&p1, 1.0, 1.0);
  point_set(p2, 1.0, 1.0);
  
  distance = point_distance(&p1, p2);
  
  point_translate(&p1, 1.0, 0.0);
  
  distance = point_distance(&p1, p2);

  point_set(&p1, 0.0, 0.0);
  point_set(p2, 3.0, 4.0);
  
  distance = point_distance(&p1, p2);
  
  printf("%f\n", distance);

  free(p2);
  p2 = NULL;

  printf("OK\n");
  return 0;
 }
Пример #4
0
int main(int argc, char **argv)
{
	struct point p1, *p2;

	point_set(&p1, 1.0, 1.0);

	p2 = malloc(sizeof(struct point));
	assert(p2);

	point_set(p2, 1.0, 1.0);
	assert(point_distance(&p1, p2) == 0.0);

	point_translate(&p1, 1.0, 0.0);
	assert(point_distance(&p1, p2) == 1.0);

	point_set(&p1, 0.0, 0.0);
	point_set(p2, 3.0, 4.0);
	assert(point_distance(&p1, p2) == 5.0);

	free(p2);
	p2 = NULL;

	printf("OK\n");
	return 0;
}
Пример #5
0
/*
 * Allocate a new point and initialize it to x,y. Then
 * add that point to the SortedPoints list. Return
 * 1 on success and 0 on error (e.g., out of memory).
 */
int sp_addNewPoint(SortedPoints *sp, double x, double y)
{
	Point ORIGIN;
	ORIGIN.x = 0;
	ORIGIN.y = 0;
        
        // Local iterator node
	Node *curr;
	
	// Allocate memory for the new node
	Node *n;
	n = (Node *)malloc(sizeof(Node));
	if (!n) return 0;  // malloc() returns a NULL pointer if not enough memory.
        
        // Initializing the new node 'n'
	n->p.x = x;
	n->p.y = y;
	
// 	Inserting the new node in the correct place in the linked list
	
	// If the list is empty, add the point as the head.
	if (sp->head == NULL) {
		sp->head = n;
		return 1;
	}

	curr = sp->head;

	while (curr != NULL) {
	
		if (point_distance(&n->p, &ORIGIN) < point_distance(&curr->p, &ORIGIN)) {
			insertBefore(sp, n, curr);
			return 1;
		}
		if(point_distance(&n->p, &ORIGIN) == point_distance(&curr->p, &ORIGIN)) {
			if(n->p.x < curr->p.x) {
				insertBefore(sp, n, curr);
				return 1;
			}
			if(n->p.x == curr->p.x && n->p.y < curr->p.y) {
				insertBefore(sp, n, curr);
				return 1;
			}
		}
		
		curr = curr->next;
	}
	
	// If we reach this point, n is not less than any of the other nodes and
	// we add it to the end of the list
	
	curr = sp->head;
	while (curr->next != NULL) curr = curr->next;
	insertAfter(n, curr);
	return 1;
}
Пример #6
0
static void QuadTree_get_nearest_internal(QuadTree qt, real *x, real *y, real *min, int *imin, int tentative, int *flag){
  /* get the narest point years to {x[0], ..., x[dim]} and store in y.*/
  SingleLinkedList l;
  real *coord, dist;
  int dim, i, iq = -1;
  real qmin;
  real *point = x;

  *flag = 0;
  if (!qt) return;
  dim = qt->dim;
  l = qt->l;
  if (l){
    while (l){
      coord = node_data_get_coord(SingleLinkedList_get_data(l));
      dist = point_distance(point, coord, dim);
      if(*min < 0 || dist < *min) {
	*min = dist;
	*imin = node_data_get_id(SingleLinkedList_get_data(l));
	for (i = 0; i < dim; i++) y[i] = coord[i];
      }
      l = SingleLinkedList_get_next(l);
    }
  }
  
  if (qt->qts){
    dist = point_distance(qt->center, point, dim); 
    if (*min >= 0 && (dist - sqrt((real) dim) * qt->width > *min)){
      return;
    } else {
      if (tentative){/* quick first approximation*/
	qmin = -1;
	for (i = 0; i < 1<<dim; i++){
	  if (qt->qts[i]){
	    dist = point_distance(qt->qts[i]->average, point, dim); 
	    if (dist < qmin || qmin < 0){
	      qmin = dist; iq = i;
	    }
	  }
	}
	assert(iq >= 0);
	QuadTree_get_nearest_internal(qt->qts[iq], x, y, min, imin, tentative, flag);
      } else {
	for (i = 0; i < 1<<dim; i++){
	  QuadTree_get_nearest_internal(qt->qts[i], x, y, min, imin, tentative, flag);
	}
      }
    }
  }

}
double triangle_area(triangle_3D triangle)
  {
    double a_length, b_length, gamma;
    point_3D a_vector, b_vector;

    a_length = point_distance(triangle.a,triangle.b);
    b_length = point_distance(triangle.a,triangle.c);

    substract_vectors(triangle.b,triangle.a,a_vector);
    substract_vectors(triangle.c,triangle.a,b_vector);

    gamma = vectors_angle(a_vector,b_vector);

    return 1/2.0 * a_length * b_length * sin(gamma);
  }
void mesh_3D::update_bounding_sphere()
  {
    unsigned int i;
    double distance;

    this->bounding_sphere_center.x = 0;
    this->bounding_sphere_center.y = 0;
    this->bounding_sphere_center.z = 0;

    for (i = 0; i < this->vertices.size(); i++)
      {
        bounding_sphere_center.x += this->vertices[i].position.x;
        bounding_sphere_center.y += this->vertices[i].position.y;
        bounding_sphere_center.z += this->vertices[i].position.z;
      }

    bounding_sphere_center.x /= this->vertices.size();
    bounding_sphere_center.y /= this->vertices.size();
    bounding_sphere_center.z /= this->vertices.size();

    this->bounding_sphere_radius = 0;

    for (i = 0; i < this->vertices.size(); i++)
      {
        distance = point_distance(this->vertices[i].position,this->bounding_sphere_center);

        if (distance > this->bounding_sphere_radius)
          this->bounding_sphere_radius = distance;
      }
  }
Пример #9
0
/*
 ** Distance from a point to a path 
 */
double *dist_ppth(Point *pt, PATH *path)
{
    double *result;
    double *tmp;
    int i;
    LSEG lseg;
    
    switch (path->npts) {
    case 0:
	result = PALLOCTYPE(double);
	*result = Abs((double) DBL_MAX);	/* +infinity */
	break;
    case 1:
	result = point_distance(pt, &path->p[0]);
	break;
    default:
	/*
	 * the distance from a point to a path is the smallest distance
	 * from the point to any of its constituent segments.
	 */
	Assert(path->npts > 1);
	result = PALLOCTYPE(double);
	for (i = 0; i < path->npts - 1; ++i) {
	    statlseg_construct(&lseg, &path->p[i], &path->p[i+1]);
	    tmp = dist_ps(pt, &lseg);
	    if (i == 0 || *tmp < *result)
		*result = *tmp;
	    PFREE(tmp);
	}
	break;
    }
    return(result);
}
Пример #10
0
void QuadTree_get_supernodes_internal(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances, real *counts, int *flag){
  SingleLinkedList l;
  real *coord, dist;
  int dim, i;

  (*counts)++;

  if (!qt) return;
  dim = qt->dim;
  l = qt->l;
  if (l){
    while (l){
      check_or_realloc_arrays(dim, nsuper, nsupermax, center, supernode_wgts, distances);
      if (node_data_get_id(SingleLinkedList_get_data(l)) != nodeid){
	coord = node_data_get_coord(SingleLinkedList_get_data(l));
	for (i = 0; i < dim; i++){
	  (*center)[dim*(*nsuper)+i] = coord[i];
	}
	(*supernode_wgts)[*nsuper] = node_data_get_weight(SingleLinkedList_get_data(l));
	(*distances)[*nsuper] = point_distance(point, coord, dim);
	(*nsuper)++;
      }
      l = SingleLinkedList_get_next(l);
    }
  }

  if (qt->qts){
    dist = point_distance(qt->center, point, dim); 
    if (qt->width < bh*dist){
      check_or_realloc_arrays(dim, nsuper, nsupermax, center, supernode_wgts, distances);
      for (i = 0; i < dim; i++){
        (*center)[dim*(*nsuper)+i] = qt->average[i];
      }
      (*supernode_wgts)[*nsuper] = qt->total_weight;
      (*distances)[*nsuper] = point_distance(qt->average, point, dim); 
      (*nsuper)++;
    } else {
      for (i = 0; i < 1<<dim; i++){
	QuadTree_get_supernodes_internal(qt->qts[i], bh, point, nodeid, nsuper, nsupermax, center, 
					 supernode_wgts, distances, counts, flag);
      }
    }
  }

}
Пример #11
0
bool CartesianPlane::point_in_plane(Point3D pt) {

    if (point_distance(pt) < 1e-12) {
        return true; }
    else {
        return false;
    };

};
Пример #12
0
double *dist_pb(Point *pt, BOX *box)
{
    Point	*tmp;
    double	*result;
    
    tmp = close_pb(pt, box);
    result = point_distance(tmp, pt);
    
    PFREE(tmp);
    return(result);
}
Пример #13
0
bool CHARACTER::is_hitting_door()
{
	bool done = false;
	for(int i = 0; i < 16 && !done; i++)
	{
		if(!game.controller->doors[i].valid)
			continue;
		if(!game.controller->get_door(i))
			continue;
		for(int j = 0; j < game.controller->doors[i].pos_count-1; j++)
		{
			if(point_distance(core.pos, game.controller->doors[i].pos[j], game.controller->doors[i].pos[j+1]) < 30.0f)
			{
				done = true;
				break;
			}
		}
	}
	return done;
}
bool scene_3D::cast_shadow_ray(point_3D position, light_3D light, double threshold, double range)
  {
    unsigned int i, j;
    triangle_3D triangle;
    double a,b,c,t,distance;
    point_3D intersection;
    point_3D light_position;
    light_position = light.get_position();

    light_position.x += random_double() * range;
    light_position.y += random_double() * range;
    light_position.z += random_double() * range;

    line_3D line(position,light_position);

    for (i = 0; i < this->meshes.size(); i++)
      {
        if (!line.intersects_sphere(this->meshes[i]->bounding_sphere_center,this->meshes[i]->bounding_sphere_radius))
          continue;

        for (j = 0; j < this->meshes[i]->triangle_indices.size(); j += 3)
          {
            triangle.a = this->meshes[i]->vertices[this->meshes[i]->triangle_indices[j]].position;
            triangle.b = this->meshes[i]->vertices[this->meshes[i]->triangle_indices[j + 1]].position;
            triangle.c = this->meshes[i]->vertices[this->meshes[i]->triangle_indices[j + 2]].position;

            if (line.intersects_triangle(triangle,a,b,c,t))
              {
                line.get_point(t,intersection);
                distance = point_distance(position,intersection);

                if (distance > threshold)
                  {
                    return false;
                  }
              }
          }
       }

    return true;
  }
Пример #15
0
static void cluster_points(array_t *clusters, array_t *points)
{
    int n = array_length(points);
    int k = array_length(clusters);

    for (int i=0; i<n; i++) {
        float distance = FLT_MAX;
        cluster_t *cl_nearest = NULL;
        point_t *p = array_at(points, i);

        for (int j=0; j<k; j++) {
            cluster_t *cl = array_at(clusters, j);
            float d = point_distance(p, &cl->centroid);
            if (d < distance) {
                distance = d;
                cl_nearest = cl;
            }
        }
        if (cl_nearest == NULL) {
            __asm__ volatile ("BKPT");
        }
        /* copy point and add to cluster */
        array_push_back(cl_nearest->points, p);
    }
Пример #16
0
int sp_addNewPoint(SortedPoints *sp, double x, double y)
{
        
	if (sp->size == 10)
	{
		printf("SortedPoint list full\n");
		return 0;
	}
	else if (sp->size > 10)
	{
		printf("List above 10 for some reason, error\n");
		return 0;
	}

	else
	{
		Point *originPointer = &originPoint;

		Point *newPoint = (Point*)malloc(sizeof(Point));
		point_set(newPoint, x, y);

		int position;
		int placePos;
		Point tempPoint;
		Point *tempPointer;

		for (position = 0; position < 10; position++)
		{

			if (sp->used[position] == 'n')
			{

				sp->pointArray[position] = *newPoint;
				sp->used[position] = 'y';
				break;
			}

			else
			{
				tempPoint = sp->pointArray[position];
				tempPointer = &tempPoint;

				if (point_distance(originPointer, newPoint) == point_distance(originPointer, tempPointer))
				{
					if (point_getX(newPoint) == point_getX(tempPointer))
					{
						if (point_getY(newPoint) < point_getY(tempPointer))
						{

							placePos = position;

							//shift everything else over
							sp_shiftPoints(sp, position);

							//this position holds newPoint
							sp->pointArray[placePos] = *newPoint;
							break;
						}
					}

					else if (point_getX(newPoint) < point_getX(tempPointer))
					{

						placePos = position;

						//shift everything else over
						sp_shiftPoints(sp, position);

						//this position holds newPoint
						sp->pointArray[placePos] = *newPoint;
						break;
					}

				}

				else if (point_distance(originPointer, newPoint) < point_distance(originPointer, tempPointer))
				{

					placePos = position;

					//shift everything else over
					sp_shiftPoints(sp, position);

					//this position holds newPoint
					sp->pointArray[placePos] = *newPoint;
					break;
				}

			}
		}		

		free(newPoint);
		//free(originPointer);
		sp->used[sp->size] = 'y';
		sp->size = sp->size + 1;

		return 1;
	}
        
	
}
Пример #17
0
neighbor_pairing_t* distance_based_neighbor_pairing_new(point_cloud_t* points,
                                                        real_t* R,
                                                        int* num_ghost_points)
{
  ASSERT(R != NULL);
  ASSERT(num_ghost_points != NULL);
#ifndef NDEBUG
  for (int i = 0; i < points->num_points; ++i)
    ASSERT(R[i] > 0.0);
#endif

  // Stick all the points into a kd-tree so that we can pair them up.
  kd_tree_t* tree = kd_tree_new(points->points, points->num_points);

  // Find the maximum radius of interaction.
  real_t R_max = -FLT_MAX;
  for (int i = 0; i < points->num_points; ++i)
    R_max = MAX(R_max, R[i]);

  // Add ghost points to the kd-tree and fetch an exchanger. This may add 
  // too many ghost points, but hopefully that won't be an issue.
  exchanger_t* ex = kd_tree_find_ghost_points(tree, points->comm, R_max);

  // We'll toss neighbor pairs into this expandable array.
  int_array_t* pair_array = int_array_new();

  for (int i = 0; i < points->num_points; ++i)
  {
    // Find all the neighbors for this point. We only count those 
    // neighbors {j} for which j > i.
    point_t* xi = &points->points[i];
    int_array_t* neighbors = kd_tree_within_radius(tree, xi, R_max);
    for (int k = 0; k < neighbors->size; ++k)
    {
      int j = neighbors->data[k];
      if (j > i)
      {
        real_t D = point_distance(xi, &points->points[j]);
        if (D < MAX(R[i], R[j]))
        {
          int_array_append(pair_array, i);
          int_array_append(pair_array, j);
        }
      }
    }
    int_array_free(neighbors);
  }

  // Create a neighbor pairing.
  int num_pairs = pair_array->size/2;
  neighbor_pairing_t* neighbors = 
    unweighted_neighbor_pairing_new("Distance-based point pairs", 
                                    num_pairs, pair_array->data, ex);

  // Set the number of ghost points referred to within the neighbor pairing.
  *num_ghost_points = kd_tree_size(tree) - points->num_points;

  // Clean up.
  int_array_release_data_and_free(pair_array); // Release control of data.
  kd_tree_free(tree);

  return neighbors;
}
Пример #18
0
VLD::VLD(const ImageScale& series, T const& P1, T const& P2) : contrast(0.0) {
	//============== initializing============//
	principleAngle.fill(0);
	descriptor.fill(0);
	weight.fill(0);

	begin_point[0]=P1.x;
	begin_point[1]=P1.y;
	end_point[0]=P2.x;
	end_point[1]=P2.y;

	float dy= float(end_point[1]- begin_point[1]), dx= float(end_point[0]- begin_point[0]);
	  distance=sqrt(dy*dy+dx*dx);

	if (distance==0)
		std::cerr<<"Two SIFT points have the same coordinate"<<std::endl;

	float radius=std::max(distance/float(dimension+1), 2.0f);//at least 2

	double mainAngle= get_orientation();//absolute angle

	int image_index=series.getIndex(radius);

	const Image<float> & ang = series.angles[image_index];
	const Image<float> & m   = series.magnitudes[image_index];
	double ratio=series.ratios[image_index];
  
 // std::cout<<std::endl<<"index of image "<<radius<<" "<<image_index<<" "<<ratio<<std::endl;
	
  int w=m.Width() ,h=m.Height();
	float r=float(radius/ratio);//series.radius_size;
	float sigma2=r*r;
	//======Computing the descriptors=====//

	for (int i=0;i<dimension; i++){
		double statistic[binNum];
    std::fill_n(statistic, binNum, 0.0);

		float xi= float(begin_point[0]+ float(i+1)/(dimension+1)*(dx));
		float yi= float(begin_point[1]+ float(i+1)/(dimension+1)*(dy));
		yi/=float(ratio);
		xi/=float(ratio);
		
    for (int y=int(yi-r);y<=int(yi+r+0.5);y++){
			for (int x=int(xi-r);x<=int(xi+r+0.5);x++){
				float d=point_distance(xi,yi,float(x),float(y));
				if (d<=r && inside(w,h,x,y,1)){
					//================angle and magnitude==========================//
					double angle;
					if (ang(y,x)>=0)
						angle=ang(y,x)-mainAngle;//relative angle
					else angle=0.0;

					//cout<<angle<<endl;
					while (angle<0)
						angle +=2*PI;
					while (angle>=2*PI)
						angle -=2*PI;

					//===============principle angle==============================//
					int index=int(angle*binNum/(2*PI)+0.5);

					double Gweight=exp(-d*d/4.5/sigma2)*(m(y,x));
          // std::cout<<"in number "<<image_index<<" "<<x<<" "<<y<<" "<<m(y,x)<<std::endl;
					if (index<binNum)
						statistic[index]+=Gweight;
					else // possible since the 0.5
						statistic[0]+=Gweight;

					//==============the descriptor===============================//
					int index2=int(angle*subdirection/(2*PI)+0.5);
					assert(index2>=0 && index2<=subdirection);

					if (index2<subdirection)
						descriptor[subdirection*i+index2]+=Gweight;
					else descriptor[subdirection*i]+=Gweight;// possible since the 0.5
				}
			}
		}
		//=====================find the biggest angle of ith SIFT==================//
		int index,second_index;
		max(statistic,weight[i],binNum,index,second_index);
		principleAngle[i]=index;
	}

  normalize_weight(descriptor);
 
  contrast= std::accumulate(weight.begin(), weight.end(), 0.0);
	contrast/=distance/ratio;
	normalize_weight(weight);
}
Пример #19
0
float KVLD(const Image<float>& I1,const Image<float>& I2,
	std::vector<keypoint>& F1, std::vector<keypoint>& F2,const std::vector<Pair>& matches,
	std::vector<Pair>& matchesFiltered,std::vector<double>& score,libNumerics::matrix<float>& E,std::vector<bool>& valide, KvldParameters& kvldParameters){
		matchesFiltered.clear();
		score.clear();

		ImageScale Chaine1(I1);
		ImageScale Chaine2(I2);

		std::cout<<"Image scale-space complete..."<<std::endl;

		float range1=getRange(I1,std::min(F1.size(),matches.size()),kvldParameters.inlierRate);
		float range2=getRange(I2,std::min(F2.size(),matches.size()),kvldParameters.inlierRate);

		size_t size=matches.size();

		////================distance map construction, for use of selecting neighbors===============//
		//std::cout<<"computing distance maps"<<std::endl;
		//libNumerics::matrix<float> dist1=libNumerics::matrix<float>::zeros(F1.size(), F1.size());
		//libNumerics::matrix<float> dist2=libNumerics::matrix<float>::zeros(F2.size(), F2.size());

		//  for (int a1=0; a1<F1.size();++a1)
		//    for (int a2=0; a2<F1.size();++a2)
		//      dist1(a1,a2)=point_distance(F1[a1],F1[a2]);

		//  for (int b1=0; b1<F2.size();++b1)
		//    for (int b2=0; b2<F2.size();++b2)
		//      dist2(b1,b2)=point_distance(F2[b1],F2[b2]);

		fill(valide.begin(),valide.end(), true);
		std::vector<double> scoretable(size, 0);
		std::vector<size_t> result(size, 0);

		//============main iteration for match verification==========//
		std::cout<<"main iteration";
		bool change=true, initial=true;

		while(change){
			std::cout<<".";
			change=false;

			fill(scoretable.begin(), scoretable.end(), 0.0);
			fill(result.begin(), result.end(), 0);
			//========substep 1: search for each match its neighbors and verify if they are gvld-consistent ============//
			for (int it1=0; it1<size-1;it1++){
				if (valide[it1]){
					size_t a1=matches[it1].first, b1=matches[it1].second;

					for (int it2=it1+1; it2<size;it2++){
						if (valide[it2]){
							size_t a2=matches[it2].first, b2=matches[it2].second;
							float dist1=point_distance(F1[a1],F1[a2]);
							float dist2=point_distance(F2[b1],F2[b2]);
							if ( dist1>min_dist && dist2>min_dist
								&& (dist1<range1 || dist2<range2)){

									if(E(it1,it2)==-1){//update E if unknow
										E(it1,it2)=-2; E(it2,it1)=-2;

										if(!kvldParameters.geometry || consistent(F1[a1],F1[a2],F2[b1],F2[b2])<distance_thres){
											VLD vld1(Chaine1,F1[a1],F1[a2]);
											VLD vld2(Chaine2,F2[b1],F2[b2]);
											//vld1.test();
											double error=vld1.difference(vld2);
											//std::cout<<std::endl<<it1<<" "<<it2<<" "<<dist1(a1,a2)<<" "<< dist2(b1,b2)<<" "<<error<<std::endl;
											if (error<juge){
												E(it1,it2)=(float)error;
												E(it2,it1)=(float)error;
												//std::cout<<E(it2,it1)<<std::endl;
											}
										}
									}

									if(E(it1,it2)>=0) {
										result[it1]+=1;
										result[it2]+=1;
										scoretable[it1]+=double(E(it1,it2));
										scoretable[it2]+=double(E(it1,it2));
										if (result[it1]>=max_connection)
											break;
									}
							}
						}
					}
				}
			}

			//========substep 2: remove false matches by K gvld-consistency criteria ============//
			for (int it=0; it<size;it++){
				if (valide[it] && result[it]<kvldParameters.K)  {valide[it]=false;change=true;}
			}
			//========substep 3: remove multiple matches to a same point by keeping the one with the best average gvld-consistency score ============//
			if(uniqueMatch){
				for (int it1=0; it1<size-1;it1++){
					if (valide[it1]){
						size_t a1=matches[it1].first, b1=matches[it1].second;

						for (int it2=it1+1; it2<size;it2++)
							if (valide[it2]){
								size_t a2=matches[it2].first, b2=matches[it2].second;

								if(a1==a2||b1==b2
									||(F1[a1].x==F1[a2].x && F1[a1].y==F1[a2].y && (F2[b1].x!=F2[b2].x || F2[b1].y!=F2[b2].y))
									||((F1[a1].x!=F1[a2].x || F1[a1].y!=F1[a2].y ) && F2[b1].x==F2[b2].x && F2[b1].y==F2[b2].y)
									){
										//cardinal comparison
										if(result[it1]>result[it2]){
											valide[it2]=false;change=true;
										}else if(result[it1]<result[it2]){
											valide[it1]=false;change=true;

										}else if(result[it1]==result[it2]){
											//score comparison
											if (scoretable[it1]>scoretable[it2]){
												valide[it1]=false;change=true;
											}else if (scoretable[it1]<scoretable[it2]){
												valide[it2]=false;change=true;
											}
										}
								}
							}
					}
				}
			}
			//========substep 4: if geometric verification is set, re-score matches by geometric-consistency, and remove poorly scored ones ============================//
			if (uniqueMatch && kvldParameters.geometry){
				for (int i=0;i<size;i++) scoretable[i]=0;

				std::vector<bool> switching;
				for (int i=0;i<size;i++) switching.push_back(false);

				for (int it1=0; it1<size;it1++){
					if (valide[it1]) {
						size_t a1=matches[it1].first, b1=matches[it1].second;
						float index=0.0f;
						int good_index=0;
						for (int it2=0; it2<size;it2++){
							if (it1!=it2 && valide[it2]){
								size_t a2=matches[it2].first, b2=matches[it2].second;
								float dist1=point_distance(F1[a1],F1[a2]);
								float dist2=point_distance(F2[b1],F2[b2]);
								if ((dist1<range1 || dist2<range2)
									&& (dist1>min_dist && dist2>min_dist)
									){
										float d=consistent(F1[a1],F1[a2],F2[b1],F2[b2]);
										scoretable[it1]+=d;
										index+=1;
										if (d<distance_thres)
											good_index++;
								}
							}
						}
						scoretable[it1]/=index;
						if (good_index<0.3f*float(index) && scoretable[it1]>1.2){switching[it1]=true;change=true;}
					}
				}
				for (int it1=0; it1<size;it1++){
					if (switching[it1])
						valide[it1]=false;
				}
			}
		}
		std::cout<<std::endl;


		//=============== generating output list ===================//
		for (int it=0; it<size;it++){
			if (valide[it]){
				matchesFiltered.push_back(matches[it]);
				score.push_back(scoretable[it]);
			}
		}
		return float(matchesFiltered.size())/matches.size();
}
bool line_3D::intersects_triangle(triangle_3D triangle, double &a, double &b, double &c, double &t)
  {
    point_3D vector1,vector2,vector3,normal;
    point_3D center;
    double bounding_sphere_radius;
    double distance_ca, distance_cb, distance_cc;

    // compute the triangle bounding sphere:

    center.x = (triangle.a.x + triangle.b.x + triangle.c.x) / 3.0;
    center.y = (triangle.a.y + triangle.b.y + triangle.c.y) / 3.0;
    center.z = (triangle.a.z + triangle.b.z + triangle.c.z) / 3.0;

    distance_ca = point_distance(center,triangle.a);
    distance_cb = point_distance(center,triangle.b);
    distance_cc = point_distance(center,triangle.c);

    bounding_sphere_radius = distance_ca;

    if (distance_cb > bounding_sphere_radius)
      bounding_sphere_radius = distance_cb;

    if (distance_cc > bounding_sphere_radius)
      bounding_sphere_radius = distance_cc;

    a = 0.0;
    b = 0.0;
    c = 0.0;

    substract_vectors(triangle.a,triangle.b,vector1);
    substract_vectors(triangle.a,triangle.c,vector2);

    cross_product(vector1,vector2,normal);

    /*
     Compute general plane equation in form
     qa * x + qb * y + qc * z + d = 0:
     */

    double qa = normal.x;
    double qb = normal.y;
    double qc = normal.z;
    double d = -1 * (qa * triangle.a.x + qb * triangle.a.y + qc * triangle.a.z);

    /* Solve for t: */

    double denominator = (qa * this->q0 + qb * this->q1 + qc * this->q2);

    if (denominator == 0)
      return false;

    t = (-qa * this->c0 - qb * this->c1 - qc * this->c2 - d) / denominator;

    /* t now contains parameter value for the intersection */

    if (t < 0.0)
      return false;

    point_3D intersection;

    this->get_point(t,intersection);  // intersection in 3D space

    if (point_distance(intersection,center) > bounding_sphere_radius)
      return false;

    // vectors from the intersection to each triangle vertex:

    substract_vectors(triangle.a,intersection,vector1);
    substract_vectors(triangle.b,intersection,vector2);
    substract_vectors(triangle.c,intersection,vector3);

    point_3D normal1, normal2, normal3;

    // now multiply the vectors to get their normals:

    cross_product(vector1,vector2,normal1);
    cross_product(vector2,vector3,normal2);
    cross_product(vector3,vector1,normal3);

    // if one of the vectors points in other direction than the others, the point is not inside the triangle:

    if (dot_product(normal1,normal2) <= 0 || dot_product(normal2,normal3) <= 0)
      return false;

    // now compute the barycentric coordinates:

    triangle_3D helper_triangle;
    double total_area;

    total_area = triangle_area(triangle);

    helper_triangle.a = intersection;
    helper_triangle.b = triangle.b;
    helper_triangle.c = triangle.c;
    a = triangle_area(helper_triangle) / total_area;

    helper_triangle.a = triangle.a;
    helper_triangle.b = intersection;
    helper_triangle.c = triangle.c;
    b = triangle_area(helper_triangle) / total_area;

    helper_triangle.a = triangle.a;
    helper_triangle.b = triangle.b;
    helper_triangle.c = intersection;
    c = triangle_area(helper_triangle) / total_area;

    return true;
  }
Пример #21
0
static void QuadTree_repulsive_force_interact(QuadTree qt1, QuadTree qt2, real *x, real *force, real bh, real p, real KP, real *counts){
  /* calculate the all to all reopulsive force and accumulate on each node of the quadtree if an interaction is possible.
     force[i*dim+j], j=1,...,dim is teh force on node i 
   */
  SingleLinkedList l1, l2;
  real *x1, *x2, dist, wgt1, wgt2, f, *f1, *f2, w1, w2;
  int dim, i, j, i1, i2, k;
  QuadTree qt11, qt12; 

  if (!qt1 || !qt2) return;
  assert(qt1->n > 0 && qt2->n > 0);
  dim = qt1->dim;

  l1 = qt1->l;
  l2 = qt2->l;

  /* far enough, calculate repulsive force */
  dist = point_distance(qt1->average, qt2->average, dim); 
  if (qt1->width + qt2->width < bh*dist){
    counts[0]++;
    x1 = qt1->average;
    w1 = qt1->total_weight;
    f1 = get_or_alloc_force_qt(qt1, dim);
    x2 = qt2->average;
    w2 = qt2->total_weight;
    f2 = get_or_alloc_force_qt(qt2, dim);
    assert(dist > 0);
    for (k = 0; k < dim; k++){
      if (p == -1){
	f = w1*w2*KP*(x1[k] - x2[k])/(dist*dist);
      } else {
	f = w1*w2*KP*(x1[k] - x2[k])/pow(dist, 1.- p);
      }
      f1[k] += f;
      f2[k] -= f;
    }
    return;
  }


  /* both at leaves, calculate repulsive force */
  if (l1 && l2){
    while (l1){
      x1 = node_data_get_coord(SingleLinkedList_get_data(l1));
      wgt1 = node_data_get_weight(SingleLinkedList_get_data(l1));
      i1 = node_data_get_id(SingleLinkedList_get_data(l1));
      f1 = get_or_assign_node_force(force, i1, l1, dim);
      l2 = qt2->l;
      while (l2){
	x2 = node_data_get_coord(SingleLinkedList_get_data(l2));
	wgt2 = node_data_get_weight(SingleLinkedList_get_data(l2));
	i2 = node_data_get_id(SingleLinkedList_get_data(l2));
	f2 = get_or_assign_node_force(force, i2, l2, dim);
	if ((qt1 == qt2 && i2 < i1) || i1 == i2) {
	  l2 = SingleLinkedList_get_next(l2);
	  continue;
	}
	counts[1]++;
	dist = distance_cropped(x, dim, i1, i2);
	for (k = 0; k < dim; k++){
	  if (p == -1){
	    f = wgt1*wgt2*KP*(x1[k] - x2[k])/(dist*dist);
	  } else {
	    f = wgt1*wgt2*KP*(x1[k] - x2[k])/pow(dist, 1.- p);
	  }
	  f1[k] += f;
	  f2[k] -= f;
	}
	l2 = SingleLinkedList_get_next(l2);
      }
      l1 = SingleLinkedList_get_next(l1);
    }
    return;
  }


  /* identical, split one */
  if (qt1 == qt2){
      for (i = 0; i < 1<<dim; i++){
	qt11 = qt1->qts[i];
	for (j = i; j < 1<<dim; j++){
	  qt12 = qt1->qts[j];
	  QuadTree_repulsive_force_interact(qt11, qt12, x, force, bh, p, KP, counts);
	}
      }
  } else {
    /* split the one with bigger box, or one not at the last level */
    if (qt1->width > qt2->width && !l1){
      for (i = 0; i < 1<<dim; i++){
	qt11 = qt1->qts[i];
	QuadTree_repulsive_force_interact(qt11, qt2, x, force, bh, p, KP, counts);
      }
    } else if (qt2->width > qt1->width && !l2){
      for (i = 0; i < 1<<dim; i++){
	qt11 = qt2->qts[i];
	QuadTree_repulsive_force_interact(qt11, qt1, x, force, bh, p, KP, counts);
      }
    } else if (!l1){/* pick one that is not at the last level */
      for (i = 0; i < 1<<dim; i++){
	qt11 = qt1->qts[i];
	QuadTree_repulsive_force_interact(qt11, qt2, x, force, bh, p, KP, counts);
      }
    } else if (!l2){
      for (i = 0; i < 1<<dim; i++){
	qt11 = qt2->qts[i];
	QuadTree_repulsive_force_interact(qt11, qt1, x, force, bh, p, KP, counts);
      }
    } else {
      assert(0); /* can be both at the leaf level since that should be catched at the beginning of this func. */
    }
  }
}
void create_boundary_generators(ptr_array_t* surface_points, 
                                ptr_array_t* surface_normals, 
                                ptr_array_t* surface_tags,
                                point_t** boundary_generators,
                                int* num_boundary_generators,
                                char*** tag_names,
                                int_array_t*** tags,
                                int* num_tags)
{
  ASSERT(surface_points->size >= 4); // surface must be closed!
  ASSERT(surface_points->size == surface_normals->size);
  ASSERT(surface_points->size == surface_tags->size);

  int num_surface_points = surface_points->size;

  // Compute the minimum distance from each surface point to its neighbors.
  real_t* h_min = polymec_malloc(sizeof(real_t) * num_surface_points);
  {
    // Dump the surface points into a kd-tree.
    point_t* surf_points = polymec_malloc(sizeof(point_t) * num_surface_points);
    for (int i = 0; i < num_surface_points; ++i)
      surf_points[i] = *((point_t*)surface_points->data[i]);
    kd_tree_t* tree = kd_tree_new(surf_points, num_surface_points);

    int neighbors[2];
    for (int i = 0; i < num_surface_points; ++i)
    {
      // Find the "nearest 2" points to the ith surface point--the first is 
      // the point itself, and the second is its nearest neighbor.
      // FIXME: Serious memory error within here. We work around it for 
      // FIXME: the moment by freshing the tree pointer, which is 
      // FIXME: corrupted. ICK!
      kd_tree_t* tree_p = tree;
      kd_tree_nearest_n(tree, &surf_points[i], 2, neighbors);
      tree = tree_p;
      ASSERT(neighbors[0] == i);
      ASSERT(neighbors[1] >= 0);
      ASSERT(neighbors[1] < num_surface_points);
      h_min[i] = point_distance(&surf_points[i], &surf_points[neighbors[1]]);
    }

    // Clean up.
    kd_tree_free(tree);
    polymec_free(surf_points);
  }

  // Generate boundary points for each surface point based on how many 
  // surfaces it belongs to. 
  ptr_array_t* boundary_points = ptr_array_new();
  string_int_unordered_map_t* tag_indices = string_int_unordered_map_new();
  ptr_array_t* boundary_tags = ptr_array_new();
  for (int i = 0; i < num_surface_points; ++i)
  {
    // Add any tags from this point to the set of existing boundary tags.
    string_slist_t* tags = surface_tags->data[i];
    for (string_slist_node_t* t_iter = tags->front; t_iter != NULL; t_iter = t_iter->next)
      string_int_unordered_map_insert(tag_indices, t_iter->value, tag_indices->size);

    // Retrieve the surface point.
    point_t* x_surf = surface_points->data[i];

    // Retrieve the list of normal vectors for this surface point.
    ptr_slist_t* normal_list = surface_normals->data[i];
    int num_normals = normal_list->size;
    vector_t normals[num_normals];
    int n_offset = 0;
    for (ptr_slist_node_t* n_iter = normal_list->front; n_iter != NULL; n_iter = n_iter->next)
      normals[n_offset++] = *((vector_t*)n_iter->value);

    // For now, let's keep things relatively simple.
    if (num_normals > 2)
    {
      polymec_error("create_boundary_generators: Too many normal vectors (%d) for surface point %d at (%g, %g, %g)",
                    num_normals, i, x_surf->x, x_surf->y, x_surf->z);
    }

    // Create boundary points based on this list of normals.
    if (num_normals == 1)
    {
      // This point only belongs to one surface, so we create boundary points 
      // on either side of it.
      point_t* x_out = polymec_malloc(sizeof(point_t));
      x_out->x = x_surf->x + h_min[i]*normals[0].x;
      x_out->y = x_surf->y + h_min[i]*normals[0].y;
      x_out->z = x_surf->z + h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x_out, polymec_free);

      point_t* x_in = polymec_malloc(sizeof(point_t));
      x_in->x = x_surf->x - h_min[i]*normals[0].x;
      x_in->y = x_surf->y - h_min[i]*normals[0].y;
      x_in->z = x_surf->z - h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x_in, polymec_free);
    }
    else if (num_normals == 2)
    {
      // This point appears at the interface between two surfaces.
      // (Or so it seems.)
      ASSERT(vector_dot(&normals[0], &normals[1]) < 0.0);

      point_t* x1 = polymec_malloc(sizeof(point_t));
      x1->x = x_surf->x + h_min[i]*normals[0].x;
      x1->y = x_surf->y + h_min[i]*normals[0].y;
      x1->z = x_surf->z + h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x1, polymec_free);

      point_t* x2 = polymec_malloc(sizeof(point_t));
      x2->x = x_surf->x - h_min[i]*normals[1].x;
      x2->y = x_surf->y - h_min[i]*normals[1].y;
      x2->z = x_surf->z - h_min[i]*normals[1].z;
      ptr_array_append_with_dtor(boundary_points, x2, polymec_free);
    }

    // Tag the boundary point appropriately.
    ptr_array_append(boundary_tags, tags); // Borrowed ref to tags.
  }

  // Move the surface points into a contiguous array.
  *boundary_generators = polymec_malloc(sizeof(point_t) * boundary_points->size);
  *num_boundary_generators = boundary_points->size;
  for (int i = 0; i < boundary_points->size; ++i)
  {
    (*boundary_generators)[i] = *((point_t*)boundary_points->data[i]);
  }

  // Transcribe the tags.
  *tag_names = polymec_malloc(sizeof(char*) * tag_indices->size);
  *tags = polymec_malloc(sizeof(int_array_t*) * tag_indices->size);
  *num_tags = tag_indices->size;
  char* tag_name;
  int pos = 0, tag_index;
  while (string_int_unordered_map_next(tag_indices, &pos, &tag_name, &tag_index))
  {
    (*tag_names)[tag_index] = string_dup(tag_name);
    (*tags)[tag_index] = int_array_new();
    for (int j = 0; j < *num_boundary_generators; ++j)
      int_array_append((*tags)[tag_index], tag_index);
  }

  // Clean up.
  string_int_unordered_map_free(tag_indices);
  polymec_free(h_min);
}
color scene_3D::compute_lighting(point_3D position, material surface_material, point_3D surface_normal)
  {
    unsigned int i, j;
    point_3D vector_to_light, vector_to_camera, reflection_vector;
    color final_color, light_color;
    double helper, intensity, distance_penalty;
    int helper_color[3];

    helper_color[0] = surface_material.ambient_intensity * surface_material.surface_color.red;
    helper_color[1] = surface_material.ambient_intensity * surface_material.surface_color.green;
    helper_color[2] = surface_material.ambient_intensity * surface_material.surface_color.blue;

    vector_to_camera.x = -1 * position.x;
    vector_to_camera.y = -1 * position.y;
    vector_to_camera.z = -1 * position.z;

    normalize(vector_to_camera);

    for (i = 0; i < this->lights.size(); i++)
      {
        unsigned int sum;

        sum = this->cast_shadow_ray(position,*this->lights[i],ERROR_OFFSET,0.0) ? 1 : 0; // main shadow ray

        for (j = 1; j < this->shadow_rays; j++) // additional shadow rays
          sum += this->cast_shadow_ray(position,*this->lights[i],ERROR_OFFSET,this->shadow_range) ? 1 : 0;

        if (sum != 0)  // at least one shadow ray hit the light
          {
            double shadow_ratio;    // how much shadow the point is in, 0.0 = full shadow, 1.0 = no shadow
            shadow_ratio = sum / ((double) this->shadow_rays);

            distance_penalty = 1.0 - point_distance(position,this->lights[i]->get_position()) / this->lights[i]->distance_factor;
            distance_penalty = distance_penalty < 0 ? 0 : pow(distance_penalty,0.25);
            intensity = this->lights[i]->get_intensity() * distance_penalty * shadow_ratio;

            substract_vectors(this->lights[i]->get_position(),position,vector_to_light);
            normalize(vector_to_light);

            helper = -1 * dot_product(vector_to_light,surface_normal);
            helper = helper < 0 ? 0 : helper;

            // add diffuse part:
            helper_color[0] += intensity * surface_material.surface_color.red * surface_material.diffuse_intensity * helper;
            helper_color[1] += intensity * surface_material.surface_color.green * surface_material.diffuse_intensity * helper;
            helper_color[2] += intensity * surface_material.surface_color.blue * surface_material.diffuse_intensity * helper;

            // add specular part:
            reflection_vector = make_reflection_vector(surface_normal,vector_to_light);
            helper = pow(dot_product(reflection_vector,vector_to_camera),surface_material.specular_exponent);
            helper = helper < 0 ? 0 : helper;
            light_color = this->lights[i]->get_color();

            helper_color[0] += intensity * surface_material.specular_intensity * helper * light_color.red;
            helper_color[1] += intensity * surface_material.specular_intensity * helper * light_color.green;
            helper_color[2] += intensity * surface_material.specular_intensity * helper * light_color.blue;
          }
      }

    final_color.red = saturate_int(helper_color[0],0,255);
    final_color.green = saturate_int(helper_color[1],0,255);
    final_color.blue = saturate_int(helper_color[2],0,255);

    return final_color;
  }
color scene_3D::cast_ray(line_3D line, double threshold, unsigned int recursion_depth)
  {
    unsigned int k, l, m;
    triangle_3D triangle;
    color final_color, helper_color, add_color;
    double depth, t;
    double *texture_coords_a, *texture_coords_b, *texture_coords_c;
    double barycentric_a, barycentric_b, barycentric_c;
    point_3D starting_point;
    point_3D normal,normal_a,normal_b,normal_c;
    point_3D reflection_vector, incoming_vector_reverse;
    material mat;
    int color_sum[3];

    line.get_point(0,starting_point);

    depth = 99999999;

    final_color.red = this->background_color.red;
    final_color.green = this->background_color.green;
    final_color.blue = this->background_color.blue;

    for (k = 0; k < this->meshes.size(); k++)
      {
        if (!line.intersects_sphere(this->meshes[k]->bounding_sphere_center,this->meshes[k]->bounding_sphere_radius))
          continue;

        for (l = 0; l < this->meshes[k]->triangle_indices.size(); l += 3)
          {
            triangle.a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].position;
            triangle.b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].position;
            triangle.c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].position;

            texture_coords_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].texture_coords;
            texture_coords_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].texture_coords;
            texture_coords_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].texture_coords;

            if (line.intersects_triangle(triangle,barycentric_a,barycentric_b,barycentric_c,t))
              {
                point_3D intersection;
                line.get_point(t,intersection);
                double distance = point_distance(starting_point,intersection);

                mat = this->meshes[k]->get_material();

                if (distance < depth && distance > threshold)  // depth test
                  {
                    depth = distance;

                    normal_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].normal;
                    normal_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].normal;
                    normal_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].normal;

                    normal.x = 0;
                    normal.y = 0;
                    normal.z = 0;

                    normal.x = barycentric_a * normal_a.x + barycentric_b * normal_b.x + barycentric_c * normal_c.x;
                    normal.y = barycentric_a * normal_a.y + barycentric_b * normal_b.y + barycentric_c * normal_c.y;
                    normal.z = barycentric_a * normal_a.z + barycentric_b * normal_b.z + barycentric_c * normal_c.z;
                    normalize(normal);  // interpolation breaks normalization

                    if (!this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture() != 0)        // 2d texture
                      {
                        double u,v;

                        u = barycentric_a * texture_coords_a[0] + barycentric_b * texture_coords_b[0] + barycentric_c * texture_coords_c[0];
                        v = barycentric_a * texture_coords_a[1] + barycentric_b * texture_coords_b[1] + barycentric_c * texture_coords_c[1];

                        color_buffer_get_pixel(this->meshes[k]->get_texture(),u * this->meshes[k]->get_texture()->width,v * this->meshes[k]->get_texture()->height,&final_color.red,&final_color.green,&final_color.blue);
                      }
                    else if (this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture_3D() != 0) // 3d texture
                      {
                        final_color = this->meshes[k]->get_texture_3D()->get_color(intersection.x,intersection.y,intersection.z);
                      }
                    else                                                                                // mesh color
                      {
                        final_color.red = 255;
                        final_color.green = 255;
                        final_color.blue = 255;
                      }

                    helper_color = compute_lighting(intersection,mat,normal);
                    final_color = multiply_colors(helper_color,final_color);

                    if (recursion_depth != 0)
                      {
                        incoming_vector_reverse = line.get_vector_to_origin();

                        if (mat.reflection > 0)                         // reflection
                          {
                            color_sum[0] = 0;
                            color_sum[1] = 0;
                            color_sum[2] = 0;

                            for (m = 0; m < this->reflection_rays; m++)
                              {
                                point_3D helper_point;
                                reflection_vector = make_reflection_vector(normal,incoming_vector_reverse);

                                reflection_vector.x *= -1;
                                reflection_vector.y *= -1;
                                reflection_vector.z *= -1;

                                if (m > 0) // alter the ray slightly
                                  alter_vector(reflection_vector,this->reflection_range);

                                helper_point.x = intersection.x + reflection_vector.x;
                                helper_point.y = intersection.y + reflection_vector.y;
                                helper_point.z = intersection.z + reflection_vector.z;

                                line_3D reflection_line(intersection,helper_point);

                                add_color = cast_ray(reflection_line,ERROR_OFFSET,recursion_depth - 1);

                                color_sum[0] += add_color.red;
                                color_sum[1] += add_color.green;
                                color_sum[2] += add_color.blue;
                              }

                            add_color.red = color_sum[0] / this->reflection_rays;
                            add_color.green = color_sum[1] / this->reflection_rays;
                            add_color.blue = color_sum[2] / this->reflection_rays;

                            final_color = interpolate_colors(final_color,add_color,mat.reflection);
                          }

                        if (mat.transparency > 0)                       // refraction
                          {
                            color_sum[0] = 0;
                            color_sum[1] = 0;
                            color_sum[2] = 0;

                            for (m = 0; m < this->refraction_rays; m++)
                              {
                                point_3D helper_point;
                                point_3D refraction_vector;
                                refraction_vector = make_refraction_vector(normal,incoming_vector_reverse,mat.refractive_index);

                                if (m > 0) // alter the ray slightly
                                  alter_vector(refraction_vector,this->refraction_range);

                                helper_point.x = intersection.x + refraction_vector.x;
                                helper_point.y = intersection.y + refraction_vector.y;
                                helper_point.z = intersection.z + refraction_vector.z;

                                line_3D refraction_line(intersection,helper_point);
                                add_color = cast_ray(refraction_line,ERROR_OFFSET,recursion_depth - 1);

                                color_sum[0] += add_color.red;
                                color_sum[1] += add_color.green;
                                color_sum[2] += add_color.blue;
                              }

                            add_color.red = color_sum[0] / this->refraction_rays;
                            add_color.green = color_sum[1] / this->refraction_rays;
                            add_color.blue = color_sum[2] / this->refraction_rays;

                            final_color = interpolate_colors(final_color,add_color,mat.transparency);
                          }
                      }
                  }
                }
              }
            }

    return final_color;
  }
Пример #25
0
int main(int argc, char *argv[]) {
	if (argc == 1) {
		puts("Use: level_edit <level_folder>");
		return 1;
	}

	qw_screen(800, 600, 0, "Projekt Defense");
	
	/* get background image from level folder */
	char lvl_bg[128] = {0};
	strcpy(lvl_bg, argv[1]);
	strcat(lvl_bg, "/background.png");
	qw_image background = qw_loadimage(lvl_bg);
	

	int max_points = 128,
	    points_i = 0;
	SDL_Point *points = malloc(sizeof(SDL_Point) * max_points);
	
	while (qw_running()) {
		qw_drawimage(background);
		
		qw_color(200, 100, 120, 255);
		qw_fillrect(qw_mousex - 2, qw_mousey - 2, 4, 4);
		
		/* waypoint placement */
		if (qw_mousedown(SDL_BUTTON_LEFT)) {
			if (points_i == 0) {
				points[points_i++] = point_new(qw_mousex, qw_mousey);
			} else {
				/* if not the first point placed: check if current point is to close to the last one */
				SDL_Point np = point_new(qw_mousex, qw_mousey);
				
				if (point_distance(points[points_i - 1], np) > 7.f)
					points[points_i++] = np;
			}
			
			/* we need more points? */
			if (points_i == max_points) {
				max_points += 128;
				points = realloc(points, sizeof(SDL_Point) * max_points);
			}
		}
		
		if (qw_keydown(QW_KEY(E))) {
			if (points_i > 1) {
				export_points(argv[1], points, points_i);
				puts("Exported!");
				qw_quit();
			}
		}

		qw_color(100, 120, 200, 255);
		SDL_RenderDrawLines(qw_renderer, points, points_i);

		qw_redraw();
		if (qw_keydown(QW_KEY(ESCAPE))) {
			qw_quit();
		}
	}
	
	free(points);
	qw_destroyimage(background);
	
	return 0;
}
Пример #26
0
void octree_insert(octree_t* tree, point_t* point, int index)
{
  if (tree->root == NULL) // Empty tree
  {
    octree_node_t* node = leaf_new(point, index);
    tree->root = node;
    ++tree->num_points;
  }
  else if (tree->root->type == OCTREE_LEAF_NODE)
  {
    point_t center = {.x = 0.5 * (tree->bbox.x1 + tree->bbox.x2),
                      .y = 0.5 * (tree->bbox.y1 + tree->bbox.y2),
                      .z = 0.5 * (tree->bbox.z1 + tree->bbox.z2)};

    // The tree consists of a single node.
    octree_node_t* root = tree->root;

    // Does the given point already exist here?
    if (point_distance(&root->leaf_node.point, point) == 0.0)
      return;

    // We need to create a branch node here.
    octree_node_t* node = root;
    tree->root = branch_new();
    int slot = find_slot(&center, point);
    tree->root->branch_node.children[slot] = node;
  }
  
  // Now we proceed with the normal logic, given that the root node 
  // is a branch node.
  ASSERT(tree->root->type == OCTREE_BRANCH_NODE);
  octree_node_t* node = tree->root;
  point_t center = {.x = 0.5 * (tree->bbox.x1 + tree->bbox.x2),
                    .y = 0.5 * (tree->bbox.y1 + tree->bbox.y2),
                    .z = 0.5 * (tree->bbox.z1 + tree->bbox.z2)};
  real_t lx = tree->bbox.x2 - tree->bbox.x1;
  real_t ly = tree->bbox.y2 - tree->bbox.y1;
  real_t lz = tree->bbox.z2 - tree->bbox.z1;
  int slot = find_slot(&center, point);
  static real_t xf[] = {-0.25, -0.25, -0.25, -0.25, +0.25, +0.25, +0.25, +0.25};
  static real_t yf[] = {-0.25, -0.25, +0.25, +0.25, -0.25, -0.25, +0.25, +0.25};
  static real_t zf[] = {-0.25, +0.25, -0.25, +0.25, -0.25, +0.25, -0.25, +0.25};
  while ((node->branch_node.children[slot] != NULL) && 
         (node->branch_node.children[slot]->type == OCTREE_BRANCH_NODE))
  {
    node = node->branch_node.children[slot];
    center.x += xf[slot]*lx;
    lx *= 0.5;
    center.y += yf[slot]*ly;
    ly *= 0.5;
    center.z += zf[slot]*lz;
    lz *= 0.5;
    slot = find_slot(&center, point);
  }
  octree_node_t* leaf = node->branch_node.children[slot];
  if (leaf == NULL)
  {
    // No leaf here, so we create a new one!
    leaf = leaf_new(point, index);
    node->branch_node.children[slot] = leaf;
    ++tree->num_points;
  }
  else
  {
    // Is the point already in this node?
    if (point_distance(&leaf->leaf_node.point, point) == 0.0)
        return;
    else
    {
      // We have to make a new branch.
      int old_slot, new_slot; 
      do
      {
        node->branch_node.children[slot] = branch_new();
        node = node->branch_node.children[slot];
        center.x += xf[slot]*lx;
        lx *= 0.5;
        center.y += yf[slot]*ly;
        ly *= 0.5;
        center.z += zf[slot]*lz;
        lz *= 0.5;
        new_slot = find_slot(&center, point);
        old_slot = find_slot(&center, &leaf->leaf_node.point);
      }
      while (new_slot == old_slot);
      node->branch_node.children[old_slot] = leaf;
      octree_node_t* new_leaf = leaf_new(point, index);
      node->branch_node.children[new_slot] = new_leaf;
      ++tree->num_points;
    }
  }
}

void octree_delete(octree_t* tree, point_t* point, int index)
{
  // FIXME
}

int octree_size(octree_t* tree)
{
  return tree->num_points;
}

static void node_clear(octree_node_t* node)
{
  if (node == NULL) 
  {
    return;
  }
  else if (node->type == OCTREE_LEAF_NODE)
  {
    polymec_free(node);
  }
  else 
  {
    ASSERT(node->type == OCTREE_BRANCH_NODE);
    for (int i = 0; i < 8; ++i)
      node_clear(node->branch_node.children[i]);
  }
}

void octree_clear(octree_t* tree)
{
  node_clear(tree->root);
  tree->root = NULL;
  tree->num_points = 0;
}