Пример #1
0
int get_rot_mat(double R[3][3],double v[3])  /* creates a rotation matrix that transforms v into z' */
{                                        /* with  (y' dot x)==0  */
	double xp[3],yp[3],zp[3];
	double mag;

	int i;
	for(i=0;i<3;i++)
		zp[i] = v[i];

	mag = normalize_vector(zp);
	if(mag==0) return(0);
	for(i=0;i<3;i++)
		R[2][i] = zp[i];

	xp[0]=1; xp[1]=0; xp[2]=0;
	cross_prod(yp,zp,xp);              /* yp = zp cross x */
	mag = normalize_vector(yp);
	if(mag==0){  yp[1]=yp[0]=0;  yp[2]=1; }

	for(i=0;i<3;i++)
		R[1][i] = yp[i];

	cross_prod(xp,yp,zp);
/*	mag = normalize_vector(xp);      this step should not be nec.  */
	for(i=0;i<3;i++)
		R[0][i] = xp[i];
	return(1);
}
Пример #2
0
static void form_rotation_matrix(
/*******************************/
    float       r[4][4],
    vector      vpn,            /* View plane normal */
    vector      vup             /* VUp vector */
) {
    vector      *rvects;        /* 3 vectors */
    int         i, j;

    /* allocate the 3 vectors */
    _new( rvects, 3 );

    rvects[2] = normalize( vpn );
    rvects[0] = normalize( cross_prod( vup, rvects[2] ) );
    rvects[1] = cross_prod( rvects[2], rvects[0] );

    identity_matrix( r );
    for (i=0; i < 3; i++) {
        for (j=0; j < 3; j++) {
            r[i][j] = rvects[i].v[j];
        }
    }

    /* free the 3 vectors */
    _free( rvects );
}
void torque(BEMRI * b, double * t)
{
	double F1[3] = {(X3-X1),(Y3-Y1),(Z3-Z1)} , F2[3] = {(X3-X2),(Y3-Y2),(Z3-Z2)};
	double r1h = sqrt(pow((X3-X1),2) + pow((Y3-Y1),2) + pow((Z3-Z1),2));
	double r2h = sqrt(pow((X3-X2),2) + pow((Y3-Y2),2) + pow((Z3-Z2),2));
	double r1cm[3] = {(X4-X1),(Y4-Y1),(Z4-Z1)} , r2cm[3] = {(X4-X2),(Y4-Y2),(Z4-Z2)};
	double t1[3], t2[3];

	for(int ii = 0; ii < 3; ii++)
	{
		F1[ii] *= G*m1*m3/pow(r1h,3);		//compute forces on each component from SMBH
		F2[ii] *= G*m2*m3/pow(r2h,3);
	}

	cross_prod(r1cm, F1, t1);				//compute the torque from R cross F
	cross_prod(r2cm, F2, t2);

	vect_add(t1, t2, t, 3);					//add the individual torques and store in t
/*
	printf("\ntorque is:");
	Vdisplay(t,3);
	Vdisplay(F1,3);
	Vdisplay(r1cm,3);
	Vdisplay(F2,3);
	Vdisplay(r2cm,3);
	anykey();
*/
}
Пример #4
0
/// Returns signed 2 theta (signed scattering angle w.r.t. to beam direction).
double DetectorInfo::signedTwoTheta(const size_t index) const {
  if (isMonitor(index))
    throw std::logic_error(
        "Two theta (scattering angle) is not defined for monitors.");

  const auto samplePos = samplePosition();
  const auto beamLine = samplePos - sourcePosition();

  if (beamLine.nullVector()) {
    throw Kernel::Exception::InstrumentDefinitionError(
        "Source and sample are at same position!");
  }
  // Get the axis defining the sign
  const auto &instrumentUpAxis =
      m_instrument->getReferenceFrame()->vecThetaSign();

  const auto sampleDetVec = position(index) - samplePos;
  double angle = sampleDetVec.angle(beamLine);

  const auto cross = beamLine.cross_prod(sampleDetVec);
  const auto normToSurface = beamLine.cross_prod(instrumentUpAxis);
  if (normToSurface.scalar_prod(cross) < 0) {
    angle *= -1;
  }
  return angle;
}
Пример #5
0
	vector<Point> outerTrees(vector<Point>& points) {
		auto cmp = [](const Point &p1, const Point &p2) -> bool {
			return p1.x == p2.x ? (p1.y < p2.y) : (p1.x < p2.x);
		};
		sort(points.begin(), points.end(), cmp);

		vector<Point> b, t; // bottom, top
		for (auto &p : points) {
			while (b.size() >= 2 && cross_prod(b[b.size()-2], b[b.size()-1], p) < 0) {
				b.pop_back();
			}
			b.push_back(p);
		}

		for (auto &p : points) {
			while (t.size() >= 2 && cross_prod(t[t.size()-2], t[t.size()-1], p) > 0) {
				t.pop_back();
			}
			t.push_back(p);
		}

		set<Point, decltype(cmp)> uniq(cmp);
		for (auto &p : b) { uniq.insert(p); }
		for (auto &p : t) { uniq.insert(p); }
		vector<Point> ans(uniq.begin(), uniq.end());
		return ans;
	}
Пример #6
0
Matrix CoordinateSystem::getRotFromCompass(CompassData& compassData, GravityData& gravityData) {
    Vector compass_vector(3);
    compass_vector(0) = compassData.x();
    compass_vector(1) = compassData.y();
    compass_vector(2) = compassData.z();
    Vector gravity_vector(3);
    gravity_vector(0) = gravityData.x();
    gravity_vector(1) = gravityData.y();
    gravity_vector(2) = gravityData.z();

    Vector East(3);
    cross_prod(compass_vector, gravity_vector, East); // East = cross(compass_vector, gravity_vector)
    double normEast = norm_2(East);

    if (normEast < 0)
        return IdentityMatrix(3);

    East /= normEast; // normalization
    gravity_vector /= norm_2(gravity_vector);

    Vector North(3);
    cross_prod(gravity_vector, East, North); // North = cross(gravity_vector, East)

    Matrix rotmat(3, 3);
    row(rotmat, 0) = East;
    row(rotmat, 1) = North;
    row(rotmat, 2) = gravity_vector;

    return Matrix(rotmat);
}
Пример #7
0
int lines_intersect(int i,int j,int k,int l,ls  lss[MAX_LS_AMOUNT])
     /* checks if two lines intersect on 3D sphere 
      see theory in paper Pulkki, V. Lokki, T. "Creating Auditory Displays
      with Multiple Loudspeakers Using VBAP: A Case Study with
      DIVA Project" in International Conference on 
      Auditory Displays -98. E-mail [email protected]
     if you want to have that paper.*/
{
  cart_vec v1;
  cart_vec v2;
  cart_vec v3, neg_v3;
  float angle;
  float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
  float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;

  cross_prod(lss[i].coords,lss[j].coords,&v1);
  cross_prod(lss[k].coords,lss[l].coords,&v2);
  cross_prod(v1,v2,&v3);

  neg_v3.x= 0.0 - v3.x;
  neg_v3.y= 0.0 - v3.y;
  neg_v3.z= 0.0 - v3.z;

  dist_ij = (vec_angle(lss[i].coords,lss[j].coords));
  dist_kl = (vec_angle(lss[k].coords,lss[l].coords));
  dist_iv3 = (vec_angle(lss[i].coords,v3));
  dist_jv3 = (vec_angle(v3,lss[j].coords));
  dist_inv3 = (vec_angle(lss[i].coords,neg_v3));
  dist_jnv3 = (vec_angle(neg_v3,lss[j].coords));
  dist_kv3 = (vec_angle(lss[k].coords,v3));
  dist_lv3 = (vec_angle(v3,lss[l].coords));
  dist_knv3 = (vec_angle(lss[k].coords,neg_v3));
  dist_lnv3 = (vec_angle(neg_v3,lss[l].coords));

  /* if one of loudspeakers is close to crossing point, don't do anything*/


  if(fabsf(dist_iv3) <= 0.01 || fabsf(dist_jv3) <= 0.01 || 
  fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 ||
     fabsf(dist_inv3) <= 0.01 || fabsf(dist_jnv3) <= 0.01 || 
     fabsf(dist_knv3) <= 0.01 || fabsf(dist_lnv3) <= 0.01 )
    return(0);


 
  if (((fabsf(dist_ij - (dist_iv3 + dist_jv3)) <= 0.01 ) &&
       (fabsf(dist_kl - (dist_kv3 + dist_lv3))  <= 0.01)) ||
      ((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01)  &&
       (fabsf(dist_kl - (dist_knv3 + dist_lnv3)) <= 0.01 ))) {
    return (1);
  } else {
    return (0);
  }
}
int true_anomaly(binary * b)
{
	double x,y,z,vx,vy,vz,r,v,k,h[3],R[3],V[3],e_vec[3],vxh1[3],vxh2[3],R_temp[3],theta,edotr;
	int rv=1;
	
	//First translate to mass 1 rest frame
	x = b->x2[0] - b->x1[0];
	y = b->x2[1] - b->x1[1];
	z = b->x2[2] - b->x1[2];
	vx = b->v2[0] - b->v1[0];
	vy = b->v2[1] - b->v1[1];
	vz = b->v2[2] - b->v1[2];
	r = sqrt(x*x + y*y + z*z);
	v = sqrt(vx*vx + vy*vy + vz*vz);
	k = G*b->mass1 + G*b->mass2;							//here k is the standard gravitational parameter G(m1 + m2)

	//put together vectors of r and v
	R[0] = x;
	R[1] = y;
	R[2] = z;
	V[0] = vx;
	V[1] = vy;
	V[2] = vz;

	//calculate vector h
	cross_prod(R,V,h);

	//calculate the eccentricity vector
	cross_prod(V,h,vxh1);
	vect_mult_scalar(vxh1, 1/k, vxh2, 3);
	vect_mult_scalar(R,-1/r,R_temp,3);

	vect_add(vxh2,R_temp,e_vec,3);

	//find true anomaly from r
	edotr = dot_prod(e_vec,R,3);

	theta = acos(edotr / ( mag(e_vec,3) * mag(R,3) ) );

	if(dot_prod(R,V,3) < 0)
	{
		rv = 0;
		//printf("\nold theta = %.3f\nnew theta = %.3f\n",theta,2*PI-theta);
		theta = 2*PI - theta;
	}

	b->true_anomaly = theta;

	return rv;

}
Пример #9
0
// draw triangle with per-vertex colors
void POV3DisplayDevice::tricolor(const float * xyz1, const float * xyz2, const float * xyz3,
                                 const float * n1,   const float * n2,   const float * n3,
                                 const float *c1, const float *c2, const float *c3) {
  float vec1[3], vec2[3], vec3[3], norm1[3], norm2[3], norm3[3];
  float leg1[3], leg2[3], trinorm[3], ang1, ang2, ang3;

  // transform the world coordinates
  (transMat.top()).multpoint3d(xyz1, vec1);
  (transMat.top()).multpoint3d(xyz2, vec2);
  (transMat.top()).multpoint3d(xyz3, vec3);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

//  write_materials();

  // Don't write degenerate triangles -- those with all normals more than 90
  // degrees from triangle normal or its inverse.
  vec_sub(leg1, vec2, vec1);
  vec_sub(leg2, vec3, vec1);
  cross_prod(trinorm, leg1, leg2);
  ang1 = dot_prod(trinorm, norm1);
  ang2 = dot_prod(trinorm, norm2);
  ang3 = dot_prod(trinorm, norm3);
  if ( ((ang1 >= 0.0) || (ang2 >= 0.0) || (ang3 >= 0.0)) &&
       ((ang1 <= 0.0) || (ang2 <= 0.0) || (ang3 <= 0.0)) ) {
    degenerate_triangles++;
    return;
  }

  // If all verticies have the same color, don't bother with per-vertex
  // coloring
  if ( (c1[0] == c2[0]) && (c1[0] == c3[0]) &&
       (c1[1] == c2[1]) && (c1[1] == c3[1]) &&
       (c1[2] == c2[2]) && (c1[2] == c3[2]) ) {
    fprintf(outfile, "VMD_triangle(");
    fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
        vec1[0], vec1[1], -vec1[2], vec2[0], vec2[1], -vec2[2], 
        vec3[0], vec3[1], -vec3[2]);
    fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
        norm1[0], norm1[1], -norm1[2], norm2[0], norm2[1], -norm2[2], 
        norm3[0], norm3[1], -norm3[2]);
    fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
        c1[0], c1[1], c1[2], 1 - mat_opacity);
  }
  else {
    fprintf(outfile, "VMD_tricolor(");
    fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
        vec1[0], vec1[1], -vec1[2], vec2[0], vec2[1], -vec2[2], 
        vec3[0], vec3[1], -vec3[2]);
    fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
        norm1[0], norm1[1], -norm1[2], norm2[0], norm2[1], -norm2[2], 
        norm3[0], norm3[1], -norm3[2]);
    fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>,rgbt<%.3f,%.3f,%.3f,%.3f>,rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
        c1[0], c1[1], c1[2], 1 - mat_opacity, c2[0], c2[1], c2[2], 
        1 - mat_opacity, c3[0], c3[1], c3[2], 1 - mat_opacity);
  }
}
Пример #10
0
int polar_cmp(Point *p1, Point *p2)
{
  int res;
  double d, x1, x2, y1, y2;

  res = cross_prod(p1, p2, P0);

  if (res == CW)
    return -1;
  else if (res == CCW)
    return 1;
  else {
    x1 = p1->x - P0->x;
    x2 = p2->x - P0->x;
    y1 = p1->y - P0->y;
    y2 = p2->y - P0->y;

    d = ((x1*x1) + (y1*y1)) - ((x2*x2) + (y2*y2));

    if (fabs(d) < EPSILON)
      return 0;
    else if (d < 0.0)
      return -1;
    else
      return 1;
  }
}
Пример #11
0
void Alaska::make_normals(COMPLEX c[NX][NY])
{
	double x_value,y_value;
	x_value=MAX_WORLD_X/NX;
	y_value=MAX_WORLD_Y/NY;

	for (int i=0;i<NX-1;i++)
	{
		for (int j=0;j<NY-1;j++)
		{
			ta[0]=x_value;
			ta[1]=0.0;
			ta[2]=(c[i+1][j].real-c[i][j].real)*scale_height;
			tb[0]=0.0;
			tb[1]=y_value;
			tb[2]=(c[i][j+1].real-c[i][j].real)*scale_height;
			cross_prod(ta,tb,tc);
			normals[i][j][0]=tc[0];
			normals[i][j][1]=tc[1];
			normals[i][j][2]=tc[2];
		}
	}

	for (int i=0;i<NX;i++)
	{
		normals[i][NX-1][0]=normals[i][0][0];
		normals[i][NX-1][1]=normals[i][0][1];
		normals[i][NX-1][2]=normals[i][0][2];

		normals[NX-1][i][0]=normals[0][i][0];
		normals[NX-1][i][1]=normals[0][i][1];
		normals[NX-1][i][2]=normals[0][i][2];
	}
}
Пример #12
0
static void tile_calc_normal_hid(scene_t *s, hid_t hid)
{
    int lvl = HID_GET_LEVEL(hid);
    int x = HID_GET_X_POS(hid);
    int y = HID_GET_Y_POS(hid);
    int x1, x2, y1, y2;
    x1 = x==0?0:x-1;
    y1 = y==0?0:y-1;
    x2 = x==(TILE_SUBTILE_HM_PER_TILE(lvl)-1)?x:x+1;
    y2 = y==(TILE_SUBTILE_HM_PER_TILE(lvl)-1)?y:y+1;
    hid_t xhid1, xhid2, yhid1, yhid2;
    HID_SET(xhid1, lvl, x1, y);
    HID_SET(xhid2, lvl, x2, y);
    HID_SET(yhid1, lvl, x, y1);
    HID_SET(yhid2, lvl, x, y2);

    GLfloat xv[3], yv[3], normal[3];

    xv[0] = scene_hid_x_coord(s, xhid1)- scene_hid_x_coord(s, xhid2);
    xv[1] = 0.0;
    xv[2] = scene_hid_lookup(s, xhid1)->height - scene_hid_lookup(s,xhid2)->height;

    yv[0] = 0.0;
    yv[1] = scene_hid_y_coord(s, yhid1)- scene_hid_y_coord(s, yhid2);
    yv[2] = scene_hid_lookup(s, yhid1)->height - scene_hid_lookup(s,yhid2)->height;

    cross_prod(xv, yv, normal);
    normalize(normal, normal, 3);
    heightmap_element_t *he = scene_hid_lookup(s, hid);
    memcpy(he->normal, normal, sizeof(GLfloat)*3);
    //printf("Normal is %f %f %f\n", normal[0], normal[1], normal[2]);

}
Пример #13
0
// draw a cylinder
void X3DDisplayDevice::cylinder_noxfrm(float *ta, float *tb, float radius, int filled) {
  if (ta[0] == tb[0] && ta[1] == tb[1] && ta[2] == tb[2]) {
    return;  // we don't serve your kind here
  }

  float height = distance(ta, tb);

  fprintf(outfile, "<Transform translation='%g %g %g' ",
          ta[0], ta[1] + (height / 2.0), ta[2]);

  float rotaxis[3];
  float cylaxdir[3];
  float yaxis[3] = {0.0, 1.0, 0.0};

  vec_sub(cylaxdir, tb, ta);
  vec_normalize(cylaxdir);
  float dp = dot_prod(yaxis, cylaxdir);

  cross_prod(rotaxis, cylaxdir, yaxis);
  vec_normalize(rotaxis);

  // if we have decent rotation vector, use it
  if ((rotaxis[0]*rotaxis[0] + 
      rotaxis[1]*rotaxis[1] + 
      rotaxis[2]*rotaxis[2]) > 0.5) { 
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='%g %g %g  %g'", 
            rotaxis[0], rotaxis[1], rotaxis[2], -acos(dp));
  } else if (dp < -0.98) {
    // if we have denormalized rotation vector, we can assume it is
    // caused by a cylinder axis that is nearly coaxial with the Y axis.
    // If this is the case, we either perform no rotation in the case of a
    // angle cosine near 1.0, or a 180 degree rotation for a cosine near -1.
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='0 0 -1 -3.14159'");
  }
  fprintf(outfile, ">\n");  
        
  fprintf(outfile, "  <Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // draw the cylinder
  fprintf(outfile, "    <Cylinder "
          "bottom='%s' height='%g' radius='%g' side='%s' top='%s' />\n", 
          filled ? "true" : "false",
          height,  
          radius, 
          "true",
          filled ? "true" : "false");

  fprintf(outfile, "  </Shape>\n");
  fprintf(outfile, "</Transform>\n");
}
void calc_total_angular_momentum(BEMRI * b)
{

	double p1[3],p2[3],p3[3],l1[3],l2[3],l3[3],temp[3];

	(*b).L = 0;

		vect_mult_scalar(V1,m1,p1,3);
		vect_mult_scalar(V2,m2,p2,3);
		vect_mult_scalar(V3,m3,p3,3);

		cross_prod(R1,p1,l1);
		cross_prod(R2,p2,l2);
		cross_prod(R3,p3,l3);

		vect_add(l1,l2,temp,3);
		vect_add(l3,temp,temp,3);
		(*b).L  = mag(temp,3);

	return;
}
Пример #15
0
template<> Math::Quaternion calculate< Math::Vector< double, 3 > >( Math::Vector< double, 3 >& orig, Math::Pose& pose1, Math::Vector< double, 3 >& pos2 )
{
	Math::Vector< double, 3 > dir = (~pose1) * pos2;
	dir = dir / ublas::norm_2( dir );

	Math::Vector< double, 3 > axis = cross_prod( orig, dir );
	
	Math::Quaternion q( axis[0], axis[1], axis[2], 1 + ublas::inner_prod( orig, dir ) );
	q.normalize();

	return pose1.rotation() * q;
}
Пример #16
0
// put in new data, and put the command
void DispCmdTriangle::putdata(const float *p1, const float *p2, 
                              const float *p3, VMDDisplayList *dobj) {
  int i;
  float tmp1[3], tmp2[3], tmp3[3];  // precompute the normal for
  for (i=0; i<3; i++) {             //   faster drawings later
     tmp1[i] = p2[i] - p1[i];
     tmp2[i] = p3[i] - p2[i];
  }
  cross_prod( tmp3, tmp1, tmp2);  
  vec_normalize(tmp3);
  set_array(p1, p2, p3, tmp3, tmp3, tmp3, dobj);
}
Пример #17
0
int convex_hull(Point *poly, int n, Point *hull)
{
  int i, min, h;

  if (n < 1)
    return 0;

  min = 0;
  P0 = &hull[0];
  *P0 = poly[0];

  for (i = 1; i < n; i++) {
    if ((poly[i].y < P0->y) || 
	((poly[i].y == P0->y) && (poly[i].x < P0->x))) {
      min = i;
      *P0 = poly[i];
    }
  }

  poly[min] = poly[0];
  poly[0] = *P0;
  h = 1;

  if (n == 1)
    return h;

  qsort(poly+1, n-1, sizeof(poly[1]),
        (int (*)(const void *, const void *))polar_cmp);

  for (i = 1; i < n; i++) {
    if ((fabs(poly[i].x - hull[0].x) > EPSILON) ||   
        (fabs(poly[i].y - hull[0].y) > EPSILON))  {
      break;
    }
  }

  if (i == n)
    return h;

  hull[h++] = poly[i++];

  for ( ; i < n; i++) {
    while ((h > 1) &&
	   (cross_prod(&poly[i], &hull[h-1], &hull[h-2]) != CCW)) {
      h--;
    }

    hull[h++] = poly[i];
  }

  return h;
}
Пример #18
0
/**
 * Establish the first surface normal. Tries to establish normal from
 * non-colinear points
 * @param vertices : All vertices
 * @return surface normal, or 0,0,0 if not found
 */
Kernel::V3D surfaceNormal(const std::vector<Kernel::V3D> &vertices) {
  auto v0 = vertices[1] - vertices[0];
  Kernel::V3D normal{0, 0, 0};
  const static double tolerance_sq = std::pow(1e-9, 2);
  // Look for normal amongst first 3 non-colinear points
  for (size_t i = 1; i < vertices.size() - 1; ++i) {
    auto v1 = vertices[i + 1] - vertices[i];
    normal = v0.cross_prod(v1);
    if (normal.norm2() > tolerance_sq) {
      break;
    }
  }
  return normal;
}
Пример #19
0
bool GeometryUtilities::spansPlane(const cv::Vec3d &x, const cv::Vec3d &y, const cv::Vec3d &z)
{
	// compute direction vectors y-x, z-x
	cv::Vec3d d1(y[0] - x[0], y[1] - x[1], y[2] - x[2]);
	cv::Vec3d d2(z[0] - x[0], z[1] - x[1], z[2] - x[2]);
	
	// cross-product between these vectors is zero length? points are colinear -> no plane
	cv::Vec3d cross_prod(d1[1]*d2[2] - d2[1]*d1[2], d1[0]*d2[2] - d2[0]*d1[2], d1[0]*d2[1] - d2[0]*d1[1]);

	if ((cross_prod[0]*cross_prod[0] + cross_prod[1]*cross_prod[1] + cross_prod[2]*cross_prod[2]) <= std::numeric_limits<double>::epsilon()) {
		return false;
	}

	return true;
}
Пример #20
0
void X3DDisplayDevice::cone(float *a, float *b, float r) {
  float ta[3], tb[3], radius;

  if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
    return;  // we don't serve your kind here
  }

  // transform the coordinates
  (transMat.top()).multpoint3d(a, ta);
  (transMat.top()).multpoint3d(b, tb);
  radius = scale_radius(r);

  float height = distance(a, b);

  fprintf(outfile, "<Transform translation='%g %g %g' ", 
          ta[0], ta[1] + (height / 2.0), ta[2]);

  float rotaxis[3];
  float cylaxdir[3];
  float yaxis[3] = {0.0, 1.0, 0.0};

  vec_sub(cylaxdir, tb, ta);
  vec_normalize(cylaxdir);
  float dp = dot_prod(yaxis, cylaxdir);

  cross_prod(rotaxis, cylaxdir, yaxis);
  vec_normalize(rotaxis);

  if ((rotaxis[0]*rotaxis[0] + 
      rotaxis[1]*rotaxis[1] + 
      rotaxis[2]*rotaxis[2]) > 0.5) { 
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='%g %g %g  %g'", 
            rotaxis[0], rotaxis[1], rotaxis[2], -acos(dp));
  }
  fprintf(outfile, ">\n");  
          
  fprintf(outfile, "  <Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // draw the cone
  fprintf(outfile, "  <Cone bottomRadius='%g' height='%g'/>\n", radius, height);

  fprintf(outfile, "  </Shape>\n");
  fprintf(outfile, "</Transform>\n");
}
Пример #21
0
float vol_p_side_lgth(int i, int j,int k, ls  lss[MAX_LS_AMOUNT] ){
  /* calculate volume of the parallelepiped defined by the loudspeaker
     direction vectors and divide it with total length of the triangle sides. 
     This is used when removing too narrow triangles. */

  float volper, lgth;
  cart_vec xprod;
  cross_prod(lss[i].coords, lss[j].coords, &xprod);
  volper = fabsf(vec_prod(xprod, lss[k].coords));
  lgth = (fabsf(vec_angle(lss[i].coords,lss[j].coords)) 
	  + fabsf(vec_angle(lss[i].coords,lss[k].coords)) 
	  + fabsf(vec_angle(lss[j].coords,lss[k].coords)));
  if(lgth>0.00001)
    return volper / lgth;
  else
    return 0.0;
}
Пример #22
0
/*
  Calculate volume of a tet_mesh by summing the volumes of all tets.
  Volume of each tet is given by:

    (1/6) * abs(dot_prod(a,cross_prod(b,c)))

  where a, b, and c are three edges of the tet that share a common
  vertex of the tet.
*/
double meshvol(struct tet_mesh *tet_mesh)
{


  struct node **nodes;
  struct tet_list *tlp;
  struct tet *tp;
  struct vector3 p1,p2,a,b,c,bxc;
  double volume;

  nodes=tet_mesh->nodes;

  volume = 0.0;

  for (tlp=tet_mesh->tet_head; tlp!=NULL; tlp=tlp->next)
  {
    tp=tlp->tet;
    p1.x=nodes[tp->node_index[0]]->x;
    p1.y=nodes[tp->node_index[0]]->y;
    p1.z=nodes[tp->node_index[0]]->z;

    p2.x=nodes[tp->node_index[1]]->x;
    p2.y=nodes[tp->node_index[1]]->y;
    p2.z=nodes[tp->node_index[1]]->z;
    vectorize(&p1,&p2,&a);

    p2.x=nodes[tp->node_index[2]]->x;
    p2.y=nodes[tp->node_index[2]]->y;
    p2.z=nodes[tp->node_index[2]]->z;
    vectorize(&p1,&p2,&b);

    p2.x=nodes[tp->node_index[3]]->x;
    p2.y=nodes[tp->node_index[3]]->y;
    p2.z=nodes[tp->node_index[3]]->z;
    vectorize(&p1,&p2,&c);

    cross_prod(&b,&c,&bxc);

    volume += fabs(dot_prod(&a,&bxc));
  }

  volume = volume/6.0;

  return(volume); 
}
Пример #23
0
// draw a square, given 3 of four points
void DispCmdSquare::putdata(float *p1, float *p2,float *p3,VMDDisplayList *dobj) {
  DispCmdSquare *ptr = (DispCmdSquare *)(dobj->append(DSQUARE, 
                                         sizeof(DispCmdSquare)));
  if (ptr == NULL)
    return;
  int i;
  float tmp1[3], tmp2[3];           // precompute the normal for
  for (i=0; i<3; i++) {             //   faster drawings later
     tmp1[i] = p2[i] - p1[i];
     tmp2[i] = p3[i] - p2[i];
  }
  cross_prod( ptr->norml, tmp1, tmp2);  
  vec_normalize(ptr->norml);

  memcpy(ptr->pos1,p1,3*sizeof(float));
  memcpy(ptr->pos2,p2,3*sizeof(float));
  memcpy(ptr->pos3,p3,3*sizeof(float));
  for (i=0; i<3; i++)
    ptr->pos4[i] = p1[i] + tmp2[i];  // compute the fourth point
}
Пример #24
0
int solid_chopper(Solid_List s, Plane_List p)
{
    Face_PointerList faceCurs;
    Seg_PointerList segCurs;
    Face newFace;
    Seg_PointerList tmpListSeg, tmpListSegHead, tmpListSeg2,tmpListSeg2old, tmp,tmp2; // lista per salvare man mano che li trovo i segmenti int int, per poi ordinare!
    int adiacenti = 0, trovato_adiacenti=0 , trovato_primo_seg=0;
    Point V1,V2,V3; // punti per fare i calcoli sul verso
    double proiezione;
    char invertito;
    Face_PointerList newFaceList, newFaceListHead, oldFaceList;
    Solid newSol;

    faceCurs = s->So.f; // assegno la lista facce
    tmpListSegHead = (Seg_PointerList) malloc (sizeof(Seg_PointerList_El));
    tmpListSeg = tmpListSegHead;

    while (faceCurs != NULL &&!trovato_primo_seg) // primo caso in un ciclo while a parte
    {
        if (faceCurs->fptr->side == 2) // se è di tipo intersezione, ma solo fra quelle sotto! (per non trovarle due volte)
        {
            // devo scorrere i segmenti della faccia fino a trovarne uno di tipo int - int
            segCurs = faceCurs->fptr->s;

            while (segCurs != NULL && !(segCurs->sptr->A->side == '0' && segCurs->sptr->B->side == '0'))
            {
                segCurs = segCurs->next; // scorro avanti
            }

            if (segCurs != NULL)
            {
                trovato_primo_seg=1;
                tmpListSeg->sptr = segCurs->sptr; // salvo
                faceCurs = faceCurs->next; // scorri avanti la lista facce
            }


        }
        if(!trovato_primo_seg){
            faceCurs = faceCurs->next; // scorri avanti la lista facce
        }
    } // fine del primo caso

    while (faceCurs != NULL) // tutti gli altri casi
    {
        if (faceCurs->fptr->side == 2) // guardiamo solo quelle sotto perchè quelle sopra trovano gli stessi segmenti
        {
            // devo scorrere i segmenti della faccia fino a trovarne uno di tipo int - int
            segCurs = faceCurs->fptr->s;

            while (segCurs != NULL && !(segCurs->sptr->A->side == '0' && segCurs->sptr->B->side == '0'))
            {
                segCurs = segCurs->next; // scorro avanti
            }

            if (segCurs != NULL)
            {
                tmpListSeg->next = (Seg_PointerList) malloc (sizeof(Seg_PointerList_El)); // alloco il next
                tmpListSeg = tmpListSeg->next; // scorro avanti
                tmpListSeg->sptr = segCurs->sptr; // salvo il segmento
            }
        }
        faceCurs = faceCurs->next; // avanti con le facce
    }

    tmpListSeg->next = NULL;

    /* a questo punto ho in tmpListSegHead una lista di tutti i segmenti di tipo int int, però DISORDINATI
     devo ordinarli in modo adiacente e antiorario rispetto al vettore normale:
     Prima li ordiniamo in modo adiacente ma in verso come viene, poi facciamo il cross tra due consecutivi, e vediamo se è concorde o discorde
     alla normale alla faccia: se lo è bene, se no INVERTIAMO IL VETTORE NORMALE, e tenendone conto per decidere interni ed esterni, ovvero:
     CASO 1 NON SI CAMBIA => il solido S1 formato da facce + ha il vettore entrante, e viceversa
     CASO 2 SI INVERTE IL VETTORE => il solido fatto da facce + ha il vettore uscente, e viceversa;
    */

    tmpListSeg = tmpListSegHead;
    tmpListSeg2old=tmpListSegHead;
    tmpListSeg2 = tmpListSegHead->next;

    if (tmpListSeg2 == NULL){
        return 1;
    }

    while (tmpListSeg->next!= NULL)
    {

        while (tmpListSeg2 != NULL && !trovato_adiacenti) // qui la condizione è inutile perchè lo deve trovare sempre! se arriva a null c'è un errore
        {
            adiacenti = ((tmpListSeg2->sptr->A == tmpListSeg->sptr->A) || (tmpListSeg2->sptr->A == tmpListSeg->sptr->B) || (tmpListSeg2->sptr->B == tmpListSeg->sptr->A) || (tmpListSeg2->sptr->B == tmpListSeg->sptr->B));
            if (adiacenti)
            {
                trovato_adiacenti=1;
                // tmplistseg2 va subito dopo tmplistseg
                if(tmpListSeg2!=tmpListSeg->next){
                    tmp = tmpListSeg->next;
                    tmp2=tmpListSeg2->next;
                    tmpListSeg->next = tmpListSeg2;
                    tmpListSeg2->next=tmp;
                    tmpListSeg2old->next=tmp2;
                }

                // l'orientamento lo vediamo dopo!

                tmpListSeg = tmpListSeg->next; // sistemo i cursori nelle posizioni per il prossimo run
                if (tmpListSeg->next != NULL) // se non sono arrivato a fine lista
                {
                    tmpListSeg2 = tmpListSeg->next;
                    tmpListSeg2old=tmpListSeg;
                }

            }
            if(!trovato_adiacenti){
                    tmpListSeg2old=tmpListSeg2;
                    tmpListSeg2 = tmpListSeg2->next; // scorro avanti se non l'ha trovato
            }
        }
        trovato_adiacenti=0;

    }

    // ora abbiamo la lista coi segmenti adiacenti, ma non ancora ordinati in verso!
    tmpListSeg = tmpListSegHead;
    tmpListSeg2 = tmpListSegHead->next; // riporto i cursori al primo e secondo posto

    if (tmpListSeg->sptr->A == tmpListSeg2->sptr->A) //vedi disegno su faiscbuk!
    {
        tmpListSeg->orient = '-'; // il primo è meno
        tmpListSeg2->orient = '+'; // il secondo è +
    }
    else if (tmpListSeg->sptr->A == tmpListSeg2->sptr->B)
    {
        tmpListSeg->orient = '-'; // il primo è meno
        tmpListSeg2->orient = '-'; // il secondo è -
    }
    else if (tmpListSeg->sptr->B == tmpListSeg2->sptr->A)
    {
        tmpListSeg->orient = '+'; // il primo è +
        tmpListSeg2->orient = '+'; // il secondo è +
    }
    else if (tmpListSeg->sptr->B == tmpListSeg2->sptr->B)
    {
        tmpListSeg->orient = '+'; // il primo è +
        tmpListSeg2->orient = '-'; // il secondo è -
    }
    // ho sistemato l'ordine dei primi 2 segmenti, ora faccio tutti gli altri

    while (tmpListSeg2->next != NULL)
    {
        if (tmpListSeg2->orient == '+')
        {
            if (tmpListSeg2->sptr->B == tmpListSeg2->next->sptr->A)
            {
                // il successivo è concorde
                tmpListSeg2->next->orient = '+';
            }
            else
            {
                // il successivo è discorde
                tmpListSeg2->next->orient = '-';
            }
        }
        else /* if (tmpListSeg2->orient == '-') */
        {
            if (tmpListSeg2->sptr->A == tmpListSeg2->next->sptr->A)
            {
                // il successivo è concorde
                tmpListSeg2->next->orient = '+';
            }
            else
            {
                // il successivo è discorce
                tmpListSeg2->next->orient = '-';
            }
        }

        tmpListSeg2 = tmpListSeg2->next; // scorro avanti
    } // fine ciclo di ordinamento
    // ora ho i segmenti della mia nuova faccia, salvati adiacenti e ordinati in tmpListSegHead!
    // ora devo capire se sono orarie o antiorarie rispetto al versore uscente
    tmpListSeg = tmpListSegHead;
    // calcolo i vettori dei primi due segmenti, tenendo conto dell'ordine!
    if (tmpListSeg->orient == '+')
    {
        V1.x = tmpListSeg->sptr->B->x - tmpListSeg->sptr->A->x;
        V1.y = tmpListSeg->sptr->B->y - tmpListSeg->sptr->A->y;
        V1.z = tmpListSeg->sptr->B->z - tmpListSeg->sptr->A->z;
    }
    else
    {
        V1.x = tmpListSeg->sptr->A->x - tmpListSeg->sptr->B->x;
        V1.y = tmpListSeg->sptr->A->y - tmpListSeg->sptr->B->y;
        V1.z = tmpListSeg->sptr->A->z - tmpListSeg->sptr->B->z;
    }

    tmpListSeg = tmpListSeg->next;
    if (tmpListSeg->orient == '+')
    {
        V2.x = tmpListSeg->sptr->B->x - tmpListSeg->sptr->A->x;
        V2.y = tmpListSeg->sptr->B->y - tmpListSeg->sptr->A->y;
        V2.z = tmpListSeg->sptr->B->z - tmpListSeg->sptr->A->z;
    }
    else
    {
        V2.x = tmpListSeg->sptr->A->x - tmpListSeg->sptr->B->x;
        V2.y = tmpListSeg->sptr->A->y - tmpListSeg->sptr->B->y;
        V2.z = tmpListSeg->sptr->A->z - tmpListSeg->sptr->B->z;
    }

    //ora ho i due vettori dei primi due segmenti


    V3 = cross_prod(V1,V2); // prodotto vettore
    #ifdef DEBUG_
    if (abs(eu_norm(V3)) < tol)
    {
        fprintf(OUTPUT, "OCHO! I due vettori sono un po' troppo paralleli! \n");
    }
    #endif
    V3 = vett_scal(V3 , 1/eu_norm(V3));  // normalizzo V3

    proiezione = dot_prod(V3 , p->pl.n);

    if ( proiezione > tol ) // maggiore della tolleranza
    {
        newFace.norm_vect.x = p->pl.n.x; // copio il vettore normale del piano nella nuova faccia SENZA INVERTIRE
        newFace.norm_vect.y = p->pl.n.y;
        newFace.norm_vect.z = p->pl.n.z;
        invertito = 0;
    }
    else if (proiezione < -tol)
    {
        newFace.norm_vect.x = -(p->pl.n.x); // copio il vettore normale del piano nella nuova faccia INVERTENDOLO
        newFace.norm_vect.y = -(p->pl.n.y);
        newFace.norm_vect.z = -(p->pl.n.z);
        invertito = 1;
    }
    #ifdef DEBUG_
    else
    {
        fprintf(OUTPUT, "OCHO! I due vettori sono un po' troppo paralleli! \n");
    }
    #endif

    newFace.s = tmpListSegHead; // assegno la lista di segmenti, che ora è ordinata, adiacente e antioraria rispetto al vettore normale
    newFace.side = 0;

    Face_add_head(newFace,Fc,&Fc); // aggiungo la nuova faccia in testa alla lista
    NUMFACCE++;

    //ai segmenti della faccia nuova devo aggiungere la faccia in head nella propria face_pointerlist f

    segCurs = Fc->F.s;
    while(segCurs!=NULL){
        faceCurs=segCurs->sptr->f;
        segCurs->sptr->f = (Face_PointerList) malloc(sizeof(Face_PointerList_El));
        segCurs->sptr->f->fptr= &(Fc->F);
        segCurs->sptr->f->next=faceCurs;
        segCurs=segCurs->next;
    }


    // aggiungo la nuova faccia al solido attuale CHE DECIDO ESSERE QUELLO CON I PUNTI +

    newFaceList = s->So.f; // salvo tmp la lista facce
    s->So.f = (Face_PointerList) malloc(sizeof(Face_PointerList_El)); // alloco
    s->So.f->fptr = &(Fc->F) ; //aggiungo la nuova faccia
    s->So.f->next = newFaceList; // accodo il resto della lista
    if (invertito) // conto di sovrascrivere il solido con i +
    {
        s->So.f->orient = '+'; // è uscente
    }
    else
    {
        s->So.f->orient = '-'; // è entrante
    }

    newFaceListHead = (Face_PointerList) malloc(sizeof(Face_PointerList_El)); // alloco PER LA FACCIA COI -
    newFaceList = newFaceListHead; // assegno il cursore

    newFaceList->fptr = &(Fc->F); // Copio la faccia nuova nel nuovo solido
    if (invertito)
    {
        newFaceList->orient = '-'; // è entrante
    }
    else
    {
        newFaceList->orient = '+'; // è uscente
    }
    newFaceList->next = NULL;

    Solid_add_head(newSol, Sol, &Sol); // ho aggiunto il nuovo solido in testa
    NUMSOL++;

    Fc->F.Sol1 = &(s->So); // sistemo i puntatori a solido della faccia nuova
    Fc->F.Sol2 = &(Sol->So);

    // ora devo dividere la lista originale in due a seconda che siano + o -
    oldFaceList = s->So.f; // assegno la prima vecchia faccia
    while (oldFaceList->next != NULL) // finchè non arrivo all'ultimo prima di NULL
    {
        if (oldFaceList->next->fptr->side == 2 || oldFaceList->next->fptr->side == 1) // se la faccia è - o - intersezione devo spostarla nella lista nuova
        {
            newFaceList->next = (Face_PointerList) malloc(sizeof(Face_PointerList_El));
            newFaceList->next = oldFaceList->next;
            newFaceList = newFaceList->next; // scorro avanti la nuova lista
            oldFaceList->next = oldFaceList->next->next; // cucio le due estremità della lista
            newFaceList->next = NULL; // termino la lista nuova
            // ora vado a modificare i puntatori a solido della faccia che ho spostato nella lista nuova
            if (newFaceList->fptr->Sol1 == &(s->So)) // se era salvato come il primo solido modifico questo
            {
                newFaceList->fptr->Sol1 = &(Sol->So);
            }
            else // se invece era Sol2 il solido che sto modificando, allora modifico quello (non faccio altri controlli)
            {
                newFaceList->fptr->Sol2 = &(Sol->So);
            }

        } else
            {
                oldFaceList = oldFaceList->next;
            }
    }

    // adesso ho le due liste divise per facce di tipo sx e dx,con la faccia nuova in comune

    // assegno la lista - al nuovo solido
    Sol->So.f = newFaceListHead;

    return 0;
}
Пример #25
0
static void spread_it(t_rvbap *x, t_float *final_gs)
// apply the sound signal to multiple panning directions
// that causes some spreading.
// See theory in paper V. Pulkki "Uniform spreading of amplitude panned
// virtual sources" in WASPAA 99

{
    t_float vscartdir[3];
    t_float spreaddir[16][3];
    t_float spreadbase[16][3];
    long i, spreaddirnum;
    t_float power;
    if(x->x_dimension == 3){
        spreaddirnum=16;
        angle_to_cart(x->x_azi,x->x_ele,vscartdir);
        new_spread_dir(x, spreaddir[0], vscartdir, x->x_spread_base);
        new_spread_base(x, spreaddir[0], vscartdir);
        cross_prod(x->x_spread_base, vscartdir, spreadbase[1]); // four orthogonal dirs
        cross_prod(spreadbase[1], vscartdir, spreadbase[2]);
        cross_prod(spreadbase[2], vscartdir, spreadbase[3]);
    
        // four between them
        for(i=0;i<3;i++) spreadbase[4][i] =  (x->x_spread_base[i] + spreadbase[1][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[5][i] =  (spreadbase[1][i] + spreadbase[2][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[6][i] =  (spreadbase[2][i] + spreadbase[3][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[7][i] =  (spreadbase[3][i] + x->x_spread_base[i]) / 2.0;
        
        // four at half spreadangle
        for(i=0;i<3;i++) spreadbase[8][i] =  (vscartdir[i] + x->x_spread_base[i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[9][i] =  (vscartdir[i] + spreadbase[1][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[10][i] =  (vscartdir[i] + spreadbase[2][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[11][i] =  (vscartdir[i] + spreadbase[3][i]) / 2.0;
        
        // four at quarter spreadangle
        for(i=0;i<3;i++) spreadbase[12][i] =  (vscartdir[i] + spreadbase[8][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[13][i] =  (vscartdir[i] + spreadbase[9][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[14][i] =  (vscartdir[i] + spreadbase[10][i]) / 2.0;
        for(i=0;i<3;i++) spreadbase[15][i] =  (vscartdir[i] + spreadbase[11][i]) / 2.0;
        
        additive_vbap(final_gs,spreaddir[0],x); 
        for(i=1;i<spreaddirnum;i++){
            new_spread_dir(x, spreaddir[i], vscartdir, spreadbase[i]);
            additive_vbap(final_gs,spreaddir[i],x); 
        }
    } else if (x->x_dimension == 2) {
        spreaddirnum=6;     
        
        angle_to_cart(x->x_azi - x->x_spread, 0, spreaddir[0]);
        angle_to_cart(x->x_azi - x->x_spread/2, 0, spreaddir[1]);
        angle_to_cart(x->x_azi - x->x_spread/4, 0, spreaddir[2]);
        angle_to_cart(x->x_azi + x->x_spread/4, 0, spreaddir[3]);
        angle_to_cart(x->x_azi + x->x_spread/2, 0, spreaddir[4]);
        angle_to_cart(x->x_azi + x->x_spread, 0, spreaddir[5]);
        
        for(i=0;i<spreaddirnum;i++)
            additive_vbap(final_gs,spreaddir[i],x); 
    } else
        return;
        
    if(x->x_spread > 70)
        for(i=0;i<x->x_ls_amount;i++){
            final_gs[i] += (x->x_spread - 70) / 30.0 * (x->x_spread - 70) / 30.0 * 10.0;
        }
    
    for(i=0,power=0.0;i<x->x_ls_amount;i++){
        power += final_gs[i] * final_gs[i];
    }
        
    power = sqrt(power);
    for(i=0;i<x->x_ls_amount;i++){
        final_gs[i] /= power;
    }
}   
Пример #26
0
void PSDisplayDevice::cylinder_approx(float *a, float *b, float r, int res, 
                                      int filled) {

   float axis[3];
   float perp1[3], perp2[3];
   float pt1[3], pt2[3];
   float cent[3];
   float theta, theta_inc;
   float my_sin, my_cos;
   float w[3], x[3], y[3], z[3];
   int n;

   DepthSortObject cyl_body, cyl_trailcap, cyl_leadcap;

   // check against degenerate cylinder
   if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) return;
   if (r <= 0) return;

   // first we compute the axis of the cylinder
   axis[0] = b[0] - a[0];
   axis[1] = b[1] - a[1];
   axis[2] = b[2] - a[2];
   vec_normalize(axis);

   // now we compute some arbitrary perpendicular to that axis
   if ((ABS(axis[0]) < ABS(axis[1])) &&
       (ABS(axis[0]) < ABS(axis[2]))) {
      perp1[0] = 0;
      perp1[1] = axis[2];
      perp1[2] = -axis[1];
   }
   else if ((ABS(axis[1]) < ABS(axis[2]))) {
      perp1[0] = -axis[2];
      perp1[1] = 0;
      perp1[2] = axis[0];
   }
   else {
      perp1[0] = axis[1];
      perp1[1] = -axis[0];
      perp1[2] = 0;
   }
   vec_normalize(perp1);

   // now we compute another vector perpendicular both to the
   // cylinder's axis and to the perpendicular we just found.
   cross_prod(perp2, axis, perp1);

   // initialize some stuff in the depth sort objects
   cyl_body.npoints = 4;
   cyl_body.color = colorIndex;

   if (filled & CYLINDER_TRAILINGCAP) {
      cyl_trailcap.npoints = 3;
      cyl_trailcap.color = colorIndex;
   }

   if (filled & CYLINDER_LEADINGCAP) {
      cyl_leadcap.npoints = 3;
      cyl_leadcap.color = colorIndex;
   }

   // we will start out with the point defined by perp2
   pt1[0] = r * perp2[0];
   pt1[1] = r * perp2[1];
   pt1[2] = r * perp2[2];
   theta = 0;
   theta_inc = (float) (VMD_TWOPI / res);
   for (n = 1; n <= res; n++) {
      // save the last point
      memcpy(pt2, pt1, sizeof(float) * 3);

      // increment the angle and compute new points
      theta += theta_inc;
      my_sin = (float) sin(theta);
      my_cos = (float) cos(theta);

      // compute the new points
      pt1[0] = r * (perp2[0] * my_cos + perp1[0] * my_sin);
      pt1[1] = r * (perp2[1] * my_cos + perp1[1] * my_sin);
      pt1[2] = r * (perp2[2] * my_cos + perp1[2] * my_sin);

      cyl_body.points = (float *) malloc(sizeof(float) * 8);
      cyl_trailcap.points = (float *) malloc(sizeof(float) * 6);
      cyl_leadcap.points = (float *) malloc(sizeof(float) * 6);
      if (!(cyl_body.points && cyl_trailcap.points && cyl_leadcap.points)) {
         // memory error
         if (!memerror) {
            memerror = 1;
            msgErr << "PSDisplayDevice: Out of memory. Some " <<
               "objects were not drawn." << sendmsg;
         }
         continue;
      }

      // we have to translate them back to their original point...
      w[0] = pt1[0] + a[0];
      w[1] = pt1[1] + a[1];
      w[2] = pt1[2] + a[2];
      x[0] = pt2[0] + a[0];
      x[1] = pt2[1] + a[1];
      x[2] = pt2[2] + a[2];
      y[0] = pt2[0] + b[0];
      y[1] = pt2[1] + b[1];
      y[2] = pt2[2] + b[2];
      z[0] = pt1[0] + b[0];
      z[1] = pt1[1] + b[1];
      z[2] = pt1[2] + b[2];

      memcpy(cyl_body.points, w, sizeof(float) * 2);
      memcpy(&cyl_body.points[2], x, sizeof(float) * 2);
      memcpy(&cyl_body.points[4], y, sizeof(float) * 2);
      memcpy(&cyl_body.points[6], z, sizeof(float) * 2);

      // finally, we have to compute the centerpoint of this cylinder...
      // we can make a slight optimization here since we know the
      // cylinder will be a parellelogram. we only need to average
      // 2 corner points to find the center.
      cent[0] = (w[0] + y[0]) / 2;
      cent[1] = (w[1] + y[1]) / 2;
      cent[2] = (w[2] + y[2]) / 2;
      cyl_body.dist = compute_dist(cent);

      // and finally the light scale
      cyl_body.light_scale = compute_light(w, x, y);

      // go ahead and add this to our depth-sort list
      memusage += sizeof(float) * 2 * cyl_body.npoints;
      points += cyl_body.npoints;
      objects++;
      depth_list.append(cyl_body);

      // Now do the same thing for the trailing end cap...
      if (filled & CYLINDER_TRAILINGCAP) {
        memcpy(&cyl_trailcap.points[0], x, sizeof(float) * 2);
        memcpy(&cyl_trailcap.points[2], w, sizeof(float) * 2);
        memcpy(&cyl_trailcap.points[4], a, sizeof(float) * 2);
      
        // finally, we have to compute the centerpoint of the triangle
        cent[0] = (x[0] + w[0] + a[0]) / 3;
        cent[1] = (x[1] + w[1] + a[1]) / 3;
        cent[2] = (x[2] + w[2] + a[2]) / 3;
        cyl_trailcap.dist = compute_dist(cent);

        // and finally the light scale
        cyl_trailcap.light_scale = compute_light(x, w, a);

        memusage += sizeof(float) * 2 * cyl_trailcap.npoints;
        points += cyl_trailcap.npoints;
        objects++;
        depth_list.append(cyl_trailcap);
      }

      // ...and the leading end cap.
      if (filled & CYLINDER_LEADINGCAP) {
        memcpy(cyl_leadcap.points, z, sizeof(float) * 2);
        memcpy(&cyl_leadcap.points[2], y, sizeof(float) * 2);
        memcpy(&cyl_leadcap.points[4], b, sizeof(float) * 2);

        // finally, we have to compute the centerpoint of the triangle
        cent[0] = (z[0] + y[0] + b[0]) / 3;
        cent[1] = (z[1] + y[1] + b[1]) / 3;
        cent[2] = (z[2] + y[2] + b[2]) / 3;
        cyl_leadcap.dist = compute_dist(cent);

        // and finally the light scale
        cyl_leadcap.light_scale = compute_light(z, y, b);

        memusage += sizeof(float) * 2 * cyl_leadcap.npoints;
        points += cyl_leadcap.npoints;
        objects++;
        depth_list.append(cyl_leadcap);
      }
   }
}
Пример #27
0
void PSDisplayDevice::cone_approx(float *a, float *b, float r) {
   // XXX add ability to change number of triangles
   const int tris = 20;

   float axis[3];
   float perp1[3], perp2[3];
   float pt1[3], pt2[3];
   float cent[3];
   float x[3], y[3], z[3];
   float theta, theta_inc;
   float my_sin, my_cos;
   int n;

   DepthSortObject depth_obj;

   // check against degenerate cone
   if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) return;
   if (r <= 0) return;

   // first we compute the axis of the cone
   axis[0] = b[0] - a[0];
   axis[1] = b[1] - a[1];
   axis[2] = b[2] - a[2];
   vec_normalize(axis);

   // now we compute some arbitrary perpendicular to that axis
   if ((ABS(axis[0]) < ABS(axis[1])) &&
       (ABS(axis[0]) < ABS(axis[2]))) {
      perp1[0] = 0;
      perp1[1] = axis[2];
      perp1[2] = -axis[1];
   }
   else if ((ABS(axis[1]) < ABS(axis[2]))) {
      perp1[0] = -axis[2];
      perp1[1] = 0;
      perp1[2] = axis[0];
   }
   else {
      perp1[0] = axis[1];
      perp1[1] = -axis[0];
      perp1[2] = 0;
   }
   vec_normalize(perp1);

   // now we compute another vector perpendicular both to the
   // cone's axis and to the perpendicular we just found.
   cross_prod(perp2, axis, perp1);

   // initialize some stuff in the depth sort object
   depth_obj.npoints = 3;
   depth_obj.color = colorIndex;

   // we will start out with the point defined by perp2
   pt1[0] = r * perp2[0];
   pt1[1] = r * perp2[1];
   pt1[2] = r * perp2[2];
   theta = 0;
   theta_inc = (float) (VMD_TWOPI / tris);
   for (n = 1; n <= tris; n++) {
      // save the last point
      memcpy(pt2, pt1, sizeof(float) * 3);

      // increment the angle and compute new points
      theta += theta_inc;
      my_sin = (float) sin(theta);
      my_cos = (float) cos(theta);

      // compute the new points
      pt1[0] = r * (perp2[0] * my_cos + perp1[0] * my_sin);
      pt1[1] = r * (perp2[1] * my_cos + perp1[1] * my_sin);
      pt1[2] = r * (perp2[2] * my_cos + perp1[2] * my_sin);

      depth_obj.points = (float *) malloc(sizeof(float) * 6);
      if (!depth_obj.points) {
         // memory error
         if (!memerror) {
            memerror = 1;
            msgErr << "PSDisplayDevice: Out of memory. Some " <<
               "objects were not drawn." << sendmsg;
         }
         continue;
      }

      // we have to translate them back to their original point...
      x[0] = pt1[0] + a[0];
      x[1] = pt1[1] + a[1];
      x[2] = pt1[2] + a[2];
      y[0] = pt2[0] + a[0];
      y[1] = pt2[1] + a[1];
      y[2] = pt2[2] + a[2];

      // now we use the apex of the cone as the third point
      z[0] = b[0];
      z[1] = b[1];
      z[2] = b[2];

      memcpy(depth_obj.points, x, sizeof(float) * 2);
      memcpy(&depth_obj.points[2], y, sizeof(float) * 2);
      memcpy(&depth_obj.points[4], z, sizeof(float) * 2);

      // finally, we have to compute the centerpoint of this
      // triangle...
      cent[0] = (x[0] + y[0] + z[0]) / 3;
      cent[1] = (x[1] + y[1] + z[1]) / 3;
      cent[2] = (x[2] + y[2] + z[2]) / 3;
      depth_obj.dist = compute_dist(cent);

      // and the light shading factor
      depth_obj.light_scale = compute_light(x, y, z);

      // go ahead and add this to our depth-sort list
      memusage += sizeof(float) * 2 * depth_obj.npoints;
      points += depth_obj.npoints;
      objects++;
      depth_list.append(depth_obj);
   }
}
Пример #28
0
void DispCmdCylinder::putdata(const float *pos1, const float *pos2, float rad, 
                      int res, int filled, VMDDisplayList *dobj) {

  float lenaxis[3];
  vec_sub(lenaxis, pos1, pos2);  // check that it's valid
  if (dot_prod(lenaxis,lenaxis) == 0.0 || res <= 0) return;

  if (lastres != res ) {
    rot[0] = cosf( (float) VMD_TWOPI / (float) res);
    rot[1] = sinf( (float) VMD_TWOPI / (float) res);
  }
  lastres = res;
  size_t size = (9 + res*3*3)*sizeof(float);

  float *pos = (float *)(dobj->append(DCYLINDER, size));
  if (pos == NULL) 
    return;

  memcpy(pos,pos1,3*sizeof(float));
  memcpy(pos+3,pos2,3*sizeof(float));
  pos[6] = rad;
  pos[7] = (float)res;
  pos[8] = (float)filled;

  float axis[3];
  vec_sub(axis, pos1, pos2);
  vec_normalize(axis);
  int i;  // find an axis not aligned with the cylinder
  if (fabs(axis[0]) < fabs(axis[1]) &&
      fabs(axis[0]) < fabs(axis[2])) {
     i = 0;
  } else if (fabs(axis[1]) < fabs(axis[2])) {
     i = 1;
  } else {
     i = 2;
  }
  float perp[3];
  perp[i] = 0;                    // this is not aligned with the cylinder
  perp[(i+1)%3] = axis[(i+2)%3];
  perp[(i+2)%3] = -axis[(i+1)%3];
  vec_normalize(perp);
  float perp2[3];
  cross_prod(perp2, axis, perp); // find a normal to the cylinder

  float *posptr = pos+9;
  float m = rot[0], n = rot[1];
  for (int h=0; h<res; h++) {
    float tmp0, tmp1, tmp2;
    
    tmp0 = m*perp[0] + n*perp2[0]; // add the normal
    tmp1 = m*perp[1] + n*perp2[1];
    tmp2 = m*perp[2] + n*perp2[2];

    posptr[0] = tmp0; // add the normal
    posptr[1] = tmp1;
    posptr[2] = tmp2;

    posptr[3] = pos2[0] + rad * tmp0; // start
    posptr[4] = pos2[1] + rad * tmp1;
    posptr[5] = pos2[2] + rad * tmp2;

    posptr[6] = posptr[3] + lenaxis[0];  // and end of the edge
    posptr[7] = posptr[4] + lenaxis[1];
    posptr[8] = posptr[5] + lenaxis[2];
    posptr += 9;
    // use angle addition formulae:
    // cos(A+B) = cos A cos B - sin A sin B
    // sin(A+B) = cos A sin B + sin A cos B
    float mtmp = rot[0]*m - rot[1]*n;
    float ntmp = rot[0]*n + rot[1]*m; 
    m = mtmp;
    n = ntmp;
  }
}
Пример #29
0
float hill_reilly_ring_pucker(SmallRing &ring, float *framepos) {
  int N = ring.num(); // the number of atoms in the current ring

#if 0
  // return the default color if this isn't a 5 or 6 ring atom
  if (N != 5 && N != 6)
    return 0.0;
    //MK added
    if (N==6) {
      //MK do Hill-Reilly for 6-membered rings
      int NP = N-3; // number of puckering parameters
      float *X = new float[N*3]; // atom co-ordinates
      float *r = new float[N*3]; // bond vectors
      float *a = new float[NP*3]; // puckering axes
      float *q = new float[NP*3]; // normalized puckering vectors
      float *n = new float[3]; // normal to reference plane
      float *p = new float[3]; // a flap normal
      float *theta = new float[NP]; // puckering parameters
      float pucker_sum;
      float max_pucker_sum;
      float *atompos;
      int curatomid, i, j, k, l;
    
      // load ring co-ordinates
      for (i=0; i<N; i++) {
        curatomid = ring[i];
        atompos = framepos + 3*curatomid;
        X[3*i] = atompos[0];
        X[3*i+1] = atompos[1];
        X[3*i+2] = atompos[2];
      }     
    
      // calculate bond vectors
      for (i=0; i<N; i++) {
        j = (i+1) % N;
        vec_sub(r+3*i,X+3*j,X+3*i);
      }
    
      // calculate puckering axes, flap normals and puckering vectors
      for (i=0; i<NP; i++) {
        k = (2*(i+1)) % N;
        j = (2*i) % N;
        l = (2*i+1) % N;
        vec_sub(a+3*i,X+3*k,X+3*j);
        cross_prod(p,r+3*j,r+3*l);
        cross_prod(q+3*i,a+3*i,p);
        vec_normalize(q+3*i);
      }
    
      // reference normal
      cross_prod(n,a+3*0,a+3*1);
      vec_normalize(n);
    
      // calculate the puckering parameters
      pucker_sum = 0.0;
    
      for (i=0; i<NP; i++) {
        theta[i] = (float(VMD_PI)/2.0f) - acosf(dot_prod(q+3*i, n));
        pucker_sum += theta[i];
      }
    
    
      // 0.6154 radians (35.26 degrees) has significance for perfect tetrahedral bond geometry (see Hill paper)
      max_pucker_sum = NP * 0.6154f;
      float pucker_scaled = pucker_sum/max_pucker_sum;
      pucker_sum = fabsf((pucker_scaled < 1.0f) ? pucker_scaled : 1.0f);
      pucker_sum = (pucker_sum < 1.0f) ? pucker_sum : 1.0f;
    
      delete [] X;
      delete [] r;
      delete [] a;
      delete [] q;
      delete [] n;
      delete [] p;
      delete [] theta;
      return pucker_sum;
    }  //end MK if N==6
    else {  //N==5 
#endif
    float *xring = new float[N];
    float *yring = new float[N];
    float *zring = new float[N];
    float *displ = new float[N];
    float *q = new float[N];
    float *phi = new float[N];
    float Q;
    int m;
    float *atompos;
    int curatomid;
    
    for (int i=0; i<N; i++) {
      curatomid = ring[i];
      atompos = framepos + 3*curatomid; // pointer arithmetic is evil :)
      xring[i] = atompos[0];
      yring[i] = atompos[1];
      zring[i] = atompos[2];
    }     
    
    atom_displ_from_mean_plane(xring, yring, zring, displ, N);

    delete [] xring;
    delete [] yring;
    delete [] zring;

    if (cremer_pople_params(N, displ, q, phi, m, Q)) {
      // Q is the puckering amplitude - i.e. the intensity of the pucker.
      Q = (Q < 2.0f) ? Q : 2.0f;  //truncate amplitude at 2
      delete [] displ;
      delete [] q;
      delete [] phi;
      return Q;
    } else {
      delete [] displ;
      delete [] q;
      delete [] phi;
      return 0.0;
    }    
#if 0
  }
#endif
}
Пример #30
0
/****************************************************************************
*
*                   Procedure calc_reciprocal_lattice
*
* Arguments:  cell: pointer to cell_type
*
* Returns: none
*
* Action:
*     Uses the direct lattice vectors in 'cell to calculate the
*     corresponding reciprocal lattice.
*
*   The relationships here are, of course:
*    b0 = (a1 x a2) / V
*    b1 = (a2 x a0) / V
*    b2 = (a0 x a1) / V
*  where V = a0 . (a1 x a2) is the cell volume, a[0..2] is the direct latticce
*   and b[0..2] is the reciprocal lattice
*
*****************************************************************************/
void calc_reciprocal_lattice(cell_type *cell)
{
  int i,j;
  point_type tvects[3],rvects[3];
  point_type tempvect;
  real V;

  /* for molecules we shouldn't even be here */
  if( cell->dim < 1 ) return;

  /* generate a copy of the direct lattice */
  for(i=0;i<cell->dim;i++){
    tvects[i].x = cell->atoms[cell->tvects[i].end].loc.x -
      cell->atoms[cell->tvects[i].begin].loc.x;
    tvects[i].y = cell->atoms[cell->tvects[i].end].loc.y -
      cell->atoms[cell->tvects[i].begin].loc.y;
    tvects[i].z = cell->atoms[cell->tvects[i].end].loc.z -
      cell->atoms[cell->tvects[i].begin].loc.z;
  }

  /* for one dimensional systems, there is nothing to do */
  if(cell->dim == 1 ){
    V = sqrt(dot_prod(&tvects[0],&tvects[0]));
    cell->recip_vects[0].x = tvects[0].x / V;
    cell->recip_vects[0].y = tvects[0].y / V;
    cell->recip_vects[0].z = tvects[0].z / V;
    return;
  }

  /*********

    for two dimensional systems, this is easiest if we
    generate a bogus third direct vector which is normalized and
    perpendicular to both a0 and a1:
     a2 = a0 x a1 / |a0 x a1|

  ***********/
  if( cell->dim == 2 ){
    cross_prod(&tvects[0],&tvects[1],&tempvect);
    normalize_vector(&tempvect,&tvects[2]);
  }

  /* calculate the cell volume */
  cross_prod(&tvects[1],&tvects[2],&tempvect);
  V = dot_prod(&tvects[0],&tempvect);

  /* now generate the reciprocal lattice vectors */
  cross_prod(&tvects[1],&tvects[2],&rvects[0]);
  scale_vector(&rvects[0],1.0/V);
  cross_prod(&tvects[2],&tvects[0],&rvects[1]);
  scale_vector(&rvects[1],1.0/V);
  if( cell->dim == 3 ){
    cross_prod(&tvects[0],&tvects[1],&rvects[2]);
    scale_vector(&rvects[2],1.0/V);
  }

  for(i=0;i<cell->dim;i++){
    cell->recip_vects[i].x = rvects[i].x;
    cell->recip_vects[i].y = rvects[i].y;
    cell->recip_vects[i].z = rvects[i].z;
  }
#ifdef DEBUG_SYMM
  printf("Reciprocal Lattice:\n");
  for(i=0;i<cell->dim;i++){
    printf("b[%d] = (%lf %lf %lf)\n",i,rvects[i].x,rvects[i].y,
           rvects[i].z);
  }

  /* check orthonormality */
  for(i=0;i<cell->dim;i++){
    for(j=0;j<cell->dim;j++){
      V = dot_prod(&tvects[i],&rvects[j]);
      printf("a[%d] . b[%d] = %lf\n",i,j,V);
    }
  }
#endif
}