Esempio n. 1
0
// discover all points using the bresenham_step
// RETURNS: number of points actually found
static inline int find_points(KZ_Point p1, KZ_Point p2, KZ_Point *points) {
  KZ_Point greatP = p2;
  KZ_Point littleP = p1;
  order_endpoints(&littleP, &greatP);
  int dx = greatP.x - littleP.x;
  int dy = greatP.y > littleP.y ? greatP.y - littleP.y : littleP.y - greatP.y;
  // y goes up if littleP.y is smaller than greatP.y, else it goes down
  int ystep = littleP.y < greatP.y ? 1 : -1;
  KZ_Point p = littleP;
  
  double pcount = point_count(p1, p2);
  double radstep = (greatP.r - littleP.r) / pcount;
  double rstep = (greatP.kr - littleP.kr) / pcount;
  double gstep = (greatP.kg - littleP.kg) / pcount;
  double bstep = (greatP.kb - littleP.kb) / pcount;

  if (pcount == 0)
    radstep = rstep = gstep = bstep = 0;

  int i = 0;
  if (dx > dy) {
    int acc  = dx/2;
    while (p.x <= greatP.x) {
      points[i] = p;
      bresenham_step(&acc, &p.x, &p.y, dx, dy, 1, ystep);
      p.kr += rstep;
      p.kg += gstep;
      p.kb += bstep;
      p.r += radstep;
      p.ared = p.kr * ambient_red;
      p.agreen = p.kg * ambient_green;
      p.ablue = p.kb * ambient_blue;
      i++;
    }
  } else {
    int  acc = dy/2;
    char up = littleP.y < greatP.y;
    while (i < pcount) {//(up ? p.y <= greatP.y : p.y >= greatP.y) {
      points[i] = p;
      bresenham_step(&acc, &p.y, &p.x, dy, dx, ystep, 1);
      p.kr += rstep;
      p.kg += gstep;
      p.kb += bstep;
      p.r += radstep;
      p.ared = p.kr * ambient_red;
      p.agreen = p.kg * ambient_green;
      p.ablue = p.kb * ambient_blue;
      i++;
    }
  }
  return i;
}
Esempio n. 2
0
static void elcount( int *npnts, int *npols )
{
   int i, apts, apls, bpts, bpls, ppts, ppls;

   getseq();

   for ( i = 0, bpls = 0; i < seqlen; i++ )
      bpls += bond_count( seq[ i ] );

   if ( bond_type == BTYPE_LINE ) {
      for ( i = 0, bpts = 0; i < seqlen; i++ )
         bpts += point_count( seq[ i ] ) - 4;
      bpts += 2;
   }
   else {
      bpts = bpls * bond_nsides * ( 1 + bond_nsegments );
      bpls *= bond_nsides * bond_nsegments + 2;
   }

   for ( i = 0, apls = 0; i < seqlen; i++ )
      apls += atom_count( seq[ i ] );

   if ( atom_type == ATYPE_POINT )
      apts = ( bond_type == BTYPE_LINE ) ? 0 : apls;
   else if ( atom_type == ATYPE_SPHERE ) {
      apts = apls * ( atom_nsides * ( atom_nsegments - 1 ) + 2 );
      apls *= atom_nsides * atom_nsegments;
   }
   else {
      apts = 20 * apls;
      apls *= 12;
   }

   if ( do_plates ) {
      ppts = ( atom_type == ATYPE_POINT || bond_type == BTYPE_LINE ) ?
         0 : 15 * seqlen;
      ppls = 2 * seqlen;
   }
   else ppts = ppls = 0;

   if ( npnts ) *npnts = apts + bpts + ppts;
   if ( npols ) *npols = apls + bpls + ppls;
}
UInt32 RigidBodyShapeCollection::ComputeMeanShape(RigidBodyShape& mean, double distribution_tolerance, double convergence_accuracy) const
{
    // minimal set of visiblity codes
    RigidBodyVisibilityCanon canon;
    ComputeVisiblityCanon(canon);

    //  re-order codes to ensure maximal ones go first
    RigidBodyConnectedVisibilityCanon connected_canon;
    UInt32 canon_result = canon.ComputeConnectedVisibilityCanon(connected_canon, distribution_tolerance);

    // must be a complete covering of all points to work
    if (canon_result != RigidBodyResult::success)
        return canon_result;

    // initialise shape
    connected_canon.ComputeApproxMeanShape(mean);

    // number of points
    size_t num_markers = connected_canon.Shape(0).NumMarkers();

    // zero vector to init markers
    Vector3 zero(0.0);

    // transform every shape to this one and update mean
    // double previous_residual_rms = DBL_MAX;
    for (size_t opt_count = 0; opt_count < 100; opt_count++)
    {
        // transform every shape and sum
        std::vector<Vector3> point_sum(num_markers, zero);
        std::vector<size_t> point_count(num_markers, 0);
        // double dx2_sum = 0.0;
        // size_t dx2_count = 0;
        for (std::vector<RigidBodyShape>::const_iterator iter_shape( shape.begin() ); iter_shape != shape.end(); iter_shape++)
        {
            RigidTransform3 T;
            iter_shape->ComputeFitTo(T, mean);
            for (size_t marker_index = 0; marker_index < num_markers; marker_index++)
            {
                const RigidBodyMarker& x = iter_shape->Marker(marker_index);
                if (x.visible)
                {
                    // transform point to be nearest to mean as we can
                    Vector3 Tx;
                    RigidTransform3::MulVec(Tx, T, x.position);
                    point_sum[marker_index] += Tx;
                    point_count[marker_index]++;

                    // form sum residuals
                    // Vector3 dx;
                    // Vector3::Sub(dx, Tx, x.position);
                    // dx2_sum += dx.Modulus2();
                    // dx2_count++;
                }
            }
        }

        // update mean and compute max difference with previous
        double max_difference = 0.0;
        for (size_t marker_index = 0; marker_index < num_markers; marker_index++)
        {
            size_t n = point_count[marker_index];
            if (n)
            {
                // compute updated marker position
                Vector3& new_position = point_sum[marker_index];
                new_position /= n;

                // compute maximum coordinate difference with previous
                RigidBodyMarker& m = mean.Marker(marker_index);
                for (size_t dimension = 0; dimension < 3; dimension++)
                {
                    double d = fabs(new_position[dimension] - m.position[dimension]);
                    if (d > max_difference)
                        max_difference = d;
                }

                // set new values
                m.position = new_position;
            }
        }

        // verify residuals as stopping criteria
        // double residual_rms = sqrt( dx2_sum / dx2_count );
        if (max_difference < convergence_accuracy)
        {
            // fprintf(stderr, "Iterations used: %u\n", opt_count);
            return RigidBodyResult::success;
        }
        // previous_residual_rms = residual_rms;
    }

    return RigidBodyResult::did_not_converge;
}
Esempio n. 4
0
static void meshedit( void )
{
   double pt[ 3 ];
   LWPntID id[ 57 ], vid[ 2 ];
   int i, j, k, n, v[ 9 ], snum;


   csMeshBegin( 0, 0, OPSEL_GLOBAL );

   if ( bond_type == BTYPE_LINE ) {
      mgMonitorBegin( "Line Bonds", NULL, seqlen );

      for ( j = 0; j < seqlen; j++ ) {
         n = point_count( seq[ j ] );
         for ( i = 0; i < n; i++ ) {
            vert_coords( seq[ j ], i, pt );
            transform_point( j * 3.4, j * 36.0, pt );
            id[ i ] = meAddPoint( pt );
         }
         n = bond_count( seq[ j ] );
         for ( i = 0; i < n; i++ ) {
            bond_info( seq[ j ], i, &v[ 0 ], &v[ 1 ], &snum );
            vid[ 0 ] = id[ v[ 0 ]];
            vid[ 1 ] = id[ v[ 1 ]];
            meAddPoly( LWPOLTYPE_FACE, NULL, surface_name( snum ), 2, vid );
         }
         if ( userabort = mgMonitorStep( 1 ))
            break;
      }
      mgMonitorDone();
   }

   if ( atom_type == ATYPE_POINT && !userabort ) {
      mgMonitorBegin( "Point Atoms", NULL, seqlen );

      for ( j = 0; j < seqlen; j++ ) {
         n = atom_count( seq[ j ] );
         for ( i = 0; i < n; i++ ) {
            atom_info( seq[ j ], i, &v[ 0 ], &snum );
            vert_coords( seq[ j ], v[ 0 ], pt );
            transform_point( j * 3.4, j * 36.0, pt );
            id[ 0 ] = meAddPoint(  pt );
            meAddPoly( LWPOLTYPE_FACE, NULL, surface_name( snum ), 1, &id[ 0 ] );
         }
         if ( userabort = mgMonitorStep( 1 ))
            break;
      }
      mgMonitorDone();
   }

   else if ( atom_type == ATYPE_DODEC && !userabort ) {
      mgMonitorBegin( "Dodecahedron Atoms", NULL, seqlen );

      for ( j = 0; j < seqlen; j++ ) {
         n = atom_count( seq[ j ] );
         for ( i = 0; i < n; i++ ) {
            atom_info( seq[ j ], i, &v[ 0 ], &snum );
            vert_coords( seq[ j ], v[ 0 ], pt );
            transform_point( j * 3.4, j * 36.0, pt );
            dodec( pt, atom_radius[ snum ], surface_name( snum ));
         }
         if ( userabort = mgMonitorStep( 1 ))
            break;
      }
      mgMonitorDone();
   }

   if ( do_plates && !userabort ) {
      mgMonitorBegin( "Base Plates", NULL, seqlen );

      for ( j = 0; j < seqlen; j++ ) {
         for ( i = 0; i < 2; i++ ) {
            plate_info( seq[ j ], i, &n, v, &snum );
            for ( k = 0; k < n; k++ ) {
               vert_coords( seq[ j ], v[ k ], pt );
               transform_point( j * 3.4, j * 36.0, pt );
               id[ k ] = meAddPoint( pt );
            }
            meAddPoly( LWPOLTYPE_FACE, NULL, surface_name( snum ), n, id );
         }
         if ( userabort = mgMonitorStep( 1 ))
            break;
      }
      mgMonitorDone();
   }

   csMeshDone( EDERR_NONE, 0 );
}
Esempio n. 5
0
// takes an array of six coordinates alternating x y z
void draw_triangle(KZ_Point a, KZ_Point b, KZ_Point c) {
  int ab_count = point_count(a, b);
  KZ_Point *ab_points = malloc((ab_count + 1) * sizeof(KZ_Point));
  if (ab_points == NULL)
    printf("ab broken\n");
  ab_count = find_points(a, b, ab_points);

  int bc_count = point_count(b, c);
  KZ_Point *bc_points = malloc((bc_count + 1) * sizeof(KZ_Point));
  if (bc_points == NULL)
    printf("bc broken\n");
  bc_count = find_points(b, c, bc_points);

  int ca_count = point_count(c, a);
  KZ_Point *ca_points = malloc((ca_count + 1) * sizeof(KZ_Point));
  if (ca_points == NULL)
    printf("ca broken\n");
  ca_count = find_points(c, a, ca_points);

#if DRAW_FILL

  // order arrays by y descending

  KZ_Point *abs;
  int abinc;
  if (ab_points[ab_count - 1].y > ab_points[0].y) {
    abs = ab_points + ab_count - 1;
    abinc = -1;
  } else {
    abs = ab_points;
    abinc = 1;
  }

  KZ_Point *bcs;
  int bcinc;
  if (bc_points[bc_count  - 1].y > bc_points[0].y) {
    bcs = bc_points + bc_count - 1;
    bcinc = -1;
  } else {
    bcs = bc_points;
    bcinc = 1;
  }

  KZ_Point *cas;
  int cainc;
  if (ca_points[ca_count  - 1].y > ca_points[0].y) {
    cas = ca_points + ca_count - 1;
    cainc = -1;
  } else {
    cas = ca_points;
    cainc = 1;
  }

  // find the mid y value
  int max_y = a.y > b.y ? a.y:b.y;
  max_y = c.y > max_y ? c.y:max_y;
  int mid_y;
  if (max_y == a.y) {
    mid_y = b.y > c.y ? b.y : c.y;
  } else if (max_y == b.y) {
    mid_y = a.y > c.y ? a.y : c.y;
  } else if (max_y == c.y) {
    mid_y = b.y > a.y ? b.y : a.y;
  } else {
    printf("mid_y can't be found\n");
    return;
  }

  //categorize lines by upper, lower, long

  KZ_Point *upper_segment = NULL;
  int upper_inc = 0;
  int upper_count = 0;
  KZ_Point *lower_segment = NULL;
  int lower_inc = 0;
  int lower_count = 0;
  KZ_Point *long_segment = NULL;
  int long_inc = 0;
  int long_count = 0;

  if (mid_y == a.y) {
    long_inc = bcinc;
    long_segment = bcs;
    long_count = bc_count;
    if (max_y == b.y) {
      upper_inc = abinc;
      upper_segment = abs;
      upper_count = ab_count;

      lower_inc = cainc;
      lower_segment = cas;
      lower_count = ca_count;
    } else if (max_y == c.y) {
      upper_inc = cainc;
      upper_segment = cas;
      upper_count = ca_count;

      lower_inc = abinc;
      lower_segment = abs;
      lower_count = ab_count;
    }
  } else if (mid_y == b.y) {
    long_inc = cainc;
    long_segment = cas;
    long_count = ca_count;
    if (max_y == a.y) {
      upper_inc = abinc;
      upper_segment = abs;
      upper_count = ab_count;

      lower_inc = bcinc;
      lower_segment = bcs;
      lower_count = bc_count;
    } else if (max_y == c.y) {
      upper_inc = bcinc;
      upper_segment = bcs;
      upper_count = bc_count;

      lower_inc = abinc;
      lower_segment = abs;
      lower_count = ab_count;
    }
  } else if (mid_y == c.y) {
    long_inc = abinc;
    long_segment = abs;
    long_count = ab_count;
    if (max_y == a.y) {
      upper_inc = cainc;
      upper_segment = cas;
      upper_count = ca_count;

      lower_inc = bcinc;
      lower_segment = bcs;
      lower_count = bc_count;
    } else if (max_y == b.y) {
      upper_inc = bcinc;
      upper_segment = bcs;
      upper_count = bc_count;

      lower_inc = cainc;
      lower_segment = cas;
      lower_count = ca_count;
    }
  }
  int longi = 0, shorti = 0;
  while (shorti * upper_inc < upper_count
         && upper_segment[shorti + upper_inc].y == upper_segment[shorti].y) {
    shorti += upper_inc;
  }  
  while (longi * long_inc < long_count
	 && (long_segment[longi + long_inc].y == long_segment[longi].y
	     || long_segment[longi].y != upper_segment[shorti].y)) {
    longi += long_inc;
  }
  while (shorti * upper_inc < upper_count && longi * long_inc < long_count) {
    draw_horizontal(upper_segment[shorti], long_segment[longi]);
    do
      shorti += upper_inc;
    while (shorti * upper_inc < upper_count - 1
           && upper_segment[shorti + upper_inc].y == upper_segment[shorti].y);
    do
	longi += long_inc;
    while (longi * long_inc < long_count - 1
	   && long_segment[longi + long_inc].y >= mid_y
	   && (long_segment[longi + long_inc].y == long_segment[longi].y
	       || (shorti * upper_inc < upper_count
		   && long_segment[longi].y != upper_segment[shorti].y)
	       || (shorti * upper_inc >= upper_count
		   && long_segment[longi].y > mid_y)));
  }
  shorti = 0;
  int stopper = long_segment[longi].y;
  while (shorti * lower_inc < lower_count - 1
 	 && (lower_segment[shorti].y > stopper
	     || lower_segment[shorti + lower_inc].y == lower_segment[shorti].y)) {
    shorti += lower_inc;
  }
  while (shorti * lower_inc < lower_count && longi * long_inc < long_count) {
    draw_horizontal(lower_segment[shorti], long_segment[longi]);
    do
      shorti += lower_inc;
    while (shorti * lower_inc < lower_count
	   && lower_segment[shorti + lower_inc].y == lower_segment[shorti].y);
    do
      longi += long_inc;
    while (longi * long_inc < long_count
	   && (long_segment[longi + long_inc].y == long_segment[longi].y
	       || (shorti * lower_inc < lower_count
		   && long_segment[longi].y != lower_segment[shorti].y)
	       || (shorti * lower_inc >= lower_count
		   && long_segment[longi].y > mid_y)));
  }
#endif

  
#if DRAW_EDGES
  int p;
  for (p = 0; p < ab_count; p++) {
    ab_points[p].r = -1;
    ab_points[p].kr = EDGE_RED;
    ab_points[p].kg = EDGE_GREEN;
    ab_points[p].kb = EDGE_BLUE;
    consider_KZ_Point(ab_points[p]);
  }
  for (p = 0; p < bc_count; p++) {
    bc_points[p].r = -1;
    bc_points[p].kr = EDGE_RED;
    bc_points[p].kg = EDGE_GREEN;
    bc_points[p].kb = EDGE_BLUE;
    consider_KZ_Point(bc_points[p]);
  }
  for (p = 0; p < ca_count; p++) {
    ca_points[p].r = -1;
    ca_points[p].kr = EDGE_RED;
    ca_points[p].kg = EDGE_GREEN;
    ca_points[p].kb = EDGE_BLUE;
    consider_KZ_Point(ca_points[p]);
  }
#endif
  
#if DRAW_VERTICES
  a.r = b.r = c.r = -1;
  a.kr = b.kr = c.kr = VERTICES_RED;
  a.kg = b.kg = c.kg = VERTICES_BLUE;
  a.kb = b.kb = c.kb = VERTICES_GREEN;
  if (pix_in_screen(a.x, a.y))
    consider_KZ_Point(a);
  if (pix_in_screen(b.x, b.y))
    consider_KZ_Point(b);
  if (pix_in_screen(c.x, c.y))
    consider_KZ_Point(c);
#endif
  

  free(ab_points);
  free(bc_points);
  free(ca_points);
}