예제 #1
0
/*
 * drawpolyf
 *
 *	draw some filled polygons
 */
void
drawpolyf()
{
	short	val;

	color(YELLOW);

	polymode(PYM_FILL);

	/*
	 * Draw a polygon using poly, parray is our array of
	 * points and 4 is the number of points in it.
	 */
	polf(4L, parray);

	color(GREEN);

	/*
	 * Draw a filled 5 sided figure by using pmv, pdr and pclos.
	 */
	pmv(0.0, 0.0, 0.0);
		pdr(3.0, 0.0, 0.0);
		pdr(3.0, 4.0, 0.0);
		pdr(-1.0, 5.0, 0.0);
		pdr(-2.0, 2.0, 0.0);
	pclos();

	color(MAGENTA);

	/*
	 * draw a filled sector representing a 1/4 circle
	 */
	arcf(1.5, -7.0, 3.0, 0, 900);

	qread(&val);
}
예제 #2
0
void parse_bt_file(const std::string &infile,
                   std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > > &data,
                   std::vector<ParseError> &errors,
		   ParseInfo &info)
{
  info.good_records = 0;
  info.bad_records = 0;
  double begintime = doubletime();
  // Memory-map file
  FILE *in = fopen(infile.c_str(), "rb");
  if (!in) throw std::runtime_error("fopen");
  struct stat statbuf;
  if (-1 == fstat(fileno(in), &statbuf)) throw std::runtime_error("fopen");
  long long len = statbuf.st_size;
  const unsigned char *in_mem = (unsigned char*) mmap(NULL, len, PROT_READ, MAP_SHARED/*|MAP_POPULATE*/, fileno(in), 0);
  const unsigned char *end = in_mem + len;
  if (in_mem == (unsigned char*)-1) throw std::runtime_error("mmap");
  if (verbose) log_f("parse_bt_file: Mapped %s (%lld KB)", infile.c_str(), len/1024);
  Source source(in_mem);
  const unsigned char *ptr = in_mem;

  int nrecords[256];
  memset(nrecords, 0, sizeof(nrecords));
  long long nvalues=0;
  
  StartOfFileRecord sofr;
  TickToTime ttt;

  std::map<std::string, unsigned long long> last_tick;
  bool out_of_order = false;
  
  while (ptr < end) {
    const unsigned char *beginning_of_record = ptr;
    try {
      unsigned int magic = read_u32(ptr);
      if (magic != 0xb0de744c) throw ParseError("Incorrect magic # at byte %d", source.pos(ptr - 4));
      unsigned int record_size = read_u32(ptr);
      if (verbose) {
        log_f("parse_bt_file:  At location %d, magic=0x%x, record size %d",
              (int)(beginning_of_record - in_mem), magic, record_size);
      }
      if (record_size + beginning_of_record > end) throw ParseError("Record size too long at byte %d (size=%d, but only %d bytes left in file)", source.pos(ptr - 4), record_size, end-beginning_of_record);
      int record_type = read_u16(ptr);
      if (record_type != RTYPE_START_OF_FILE && record_type != RTYPE_RTC && record_type != RTYPE_PERIODIC_DATA) {
        throw ParseError("Unknown record type 0x%x at byte %d", record_type, source.pos(ptr - 2));
      }
      const unsigned char *payload = ptr;
      unsigned int payload_len = record_size-14;
      ptr += payload_len;
      if (verbose) log_f("parse_bt_file: Got record type %d, payload len %d", record_type, payload_len);
      unsigned int crc = read_u32(ptr);
      unsigned int calculated_crc = crc32(beginning_of_record, record_size - 4, 0);
      if (crc != calculated_crc) {
        // Recoverable error;  add to errors and try to continue
        errors.push_back(ParseError("Incorrect CRC32 byte %d.  read 0x%x != calculated 0x%x",
                                    source.pos(ptr - 4), crc, calculated_crc));
	if (record_type == RTYPE_PERIODIC_DATA) info.bad_records++;
        continue;
      }

      switch (record_type) {
      case RTYPE_START_OF_FILE:
        sofr = StartOfFileRecord(source, payload, payload_len);
        ttt.receive_binrec(sofr);
	info.channel_specs = sofr.channel_specs;
        break;
      case RTYPE_RTC:
      {
        RtcRecord rtcr(source, payload, payload_len);
        ttt.receive_binrec(rtcr);
        if (verbose) log_f("parse_bt_file: %s", rtcr.to_string().c_str());
      }
      break;
      case RTYPE_PERIODIC_DATA:
      {
        PeriodicDataRecord pdr(source, payload, payload_len, &sofr);
        ttt.receive_binrec(pdr);
        pdr.set_time(ttt);
        for (unsigned i = 0; i < pdr.n_channels(); i++) {
          std::string channel_name = pdr.channel_name(i);
          nvalues += pdr.number_of_samples;
          log_f("parse_pt_file: %d samples, start tick 0x%x (%u)",
                pdr.number_of_samples, pdr.first_sample_short_tick, pdr.first_sample_short_tick);
          std::vector<DataSample<double> > data_samples;
          pdr.get_data_samples(i, data_samples);

          if (data_samples.size()) {
            if (data.find(channel_name) == data.end()) {
              data[channel_name].reset(new std::vector<DataSample<double> >());
            } else {
              if (data[channel_name]->back().time > data_samples.front().time) {
                if (verbose) log_f("Warning: sample times in channel %s are out-of-order (%f > %f)",
                                   channel_name.c_str(),
                                   data[channel_name]->back().time, data_samples.front().time);
                out_of_order = true;
              }
            }
            
            data[channel_name]->insert(data[channel_name]->end(), data_samples.begin(), data_samples.end());
	    info.good_records++;
          }
          last_tick[channel_name] = pdr.first_sample_long_tick;
          
          
        }
      }
      break;
      default:
        assert(0);
      }
      nrecords[record_type]++;
    }
    catch (ParseError &e) {
      errors.push_back(ParseError("In record starting at byte %d in file %s: %s",
                                  source.pos(beginning_of_record), infile.c_str(), e.what()));
      info.bad_records++;
    }
  }
  
  if (-1 == munmap((void*)in_mem, len)) { perror("munmap"); exit(1); }
  fclose(in);
  
  if (out_of_order) {
    for (std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > >::iterator i =
           data.begin(); i != data.end(); ++i) {
      
      simple_shared_ptr<std::vector<DataSample<double > > > samples = i->second;
      std::sort(samples->begin(), samples->end(), DataSample<double>::time_lessthan);
    }
  }

  // Check samples are in order
  for (std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > >::iterator i =
         data.begin(); i != data.end(); ++i) {
    
    simple_shared_ptr<std::vector<DataSample<double > > > samples = i->second;
    for (unsigned i = 0; i < samples->size()-1; i++) {
      assert((*samples)[i].time <= ((*samples)[i+1].time));
    }
  }

  double duration = doubletime() - begintime;
  log_f("parse_bt_file: Parsed %lld bytes in %g seconds (%dK/sec)", len, duration, (int)(len / duration / 1024));
  if (verbose) {
    log_f("parse_bt_file: %d RTYPE_START_OF_FILE records", nrecords[RTYPE_START_OF_FILE]);
    log_f("parse_bt_file: %d RTYPE_RTC records", nrecords[RTYPE_RTC]);
    log_f("parse_bt_file: %d RTYPE_PERIODIC_DATA records", nrecords[RTYPE_PERIODIC_DATA]);
    log_f("parse_bt_file:    %lld values", nvalues);
  }
}
예제 #3
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * pdr2
 *
 *	add another vertex to the polygon array
 */
void
pdr2(float x, float y)
{
	pdr(x, y, vdevice.cpW[V_Z]);
}
예제 #4
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * pdr2s
 *
 *	The short argument version of pdr2.
 */
void
pdr2s(Scoord x, Scoord y)
{
	pdr((float)x, (float)y, vdevice.cpW[V_Z]);
}
예제 #5
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * pdr2i
 *
 *	The integer argument version of pdr2.
 */
void
pdr2i(Icoord x, Icoord y)
{
	pdr((float)x, (float)y, vdevice.cpW[V_Z]);
}
예제 #6
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * pdri
 *
 *	The integer argument version of pdr.
 */
void
pdri(Icoord x, Icoord y, Icoord z)
{
	pdr((float)x, (float)y, (float)z);
}
예제 #7
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdr2s
 *
 *	relative polygon draw - only (x, y). Scoord version.
 */
void
rpdr2s(Scoord dx, Scoord dy)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]);
}
예제 #8
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdrs
 *
 *	relative polygon draw. Icoord version.
 */
void
rpdrs(Scoord dx, Scoord dy, Scoord dz)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz));
}
예제 #9
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdr2i
 *
 *	relative polygon draw - only (x, y). Icoord version.
 */
void
rpdr2i(Icoord dx, Icoord dy)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]);
}
예제 #10
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdri
 *
 *	relative polygon draw. Icoord version.
 */
void
rpdri(Icoord dx, Icoord dy, Icoord dz)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz));
}
예제 #11
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdr2
 *
 *	relative polygon draw - only (x, y).
 */
void
rpdr2(Coord dx, Coord dy)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]);
}
예제 #12
0
파일: polygons.c 프로젝트: berndf/avg_q
/*
 * rpdr
 *
 *	relative polygon draw.
 */
void
rpdr(Coord dx, Coord dy, Coord dz)
{
	pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz));
}