Пример #1
0
void C_OUTLINE::plot(                //draw it
                     ScrollView* window,       // window to draw in
                     ScrollView::Color colour  // colour to draw in
                    ) const {
  inT16 stepindex;               // index to cstep
  ICOORD pos;                    // current position
  DIR128 stepdir;                // direction of step

  pos = start;                   // current position
  window->Pen(colour);
  if (stepcount == 0) {
    window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
    return;
  }
  window->SetCursor(pos.x(), pos.y());

  stepindex = 0;
  while (stepindex < stepcount) {
    pos += step(stepindex);    // step to next
    stepdir = step_dir(stepindex);
    stepindex++;               // count steps
    // merge straight lines
    while (stepindex < stepcount &&
           stepdir.get_dir() == step_dir(stepindex).get_dir()) {
      pos += step(stepindex);
      stepindex++;
    }
    window->DrawTo(pos.x(), pos.y());
  }
}
Пример #2
0
	OUTLINE::OUTLINE(PointS startpt, const vector<DIR>& new_steps)
		:start(startpt), stepcount(static_cast<int16_t>(new_steps.size())), steps(elem_num(stepcount)){
		PointS pos = start;
		box = RectS(pos, pos);
		auto lastdir = new_steps.back();
		auto prevdir = lastdir;
		int stepindex = 0;
		for (int srcindex = 0; srcindex < new_steps.size(); ++srcindex, ++stepindex){
			auto dir = new_steps[srcindex];
			set_step(stepindex, dir);
			pos += dir;
			box += pos;
			if (dir.isReverse(prevdir) && stepindex > 0){
				stepindex -= 2;
				prevdir = stepindex == -1 ? lastdir : step_dir(stepindex);
			}
			else{
				prevdir = dir;
			}
		}

		assert(pos.x == start.x&&pos.y == start.y);//ÂÖÀª±ØÐë·â±Õ
		int begin = 0;
		while (stepindex - 1 > begin && step_dir(begin).isReverse(step_dir(stepindex - 1))){
			start += step_dir(begin); //ÆðµãÏòÇ°ÒÆ
			++begin;
			--stepindex; //cancel there-and-back
		}
		for (int i = begin; i < stepindex; ++i){
			set_step(i - begin, step_dir(i));
		}
		stepcount = stepindex - begin;
		assert(stepcount >= 4);

	}
Пример #3
0
/**********************************************************************
 * C_OUTLINE::C_OUTLINE
 *
 * Constructor to build a C_OUTLINE from a C_OUTLINE_FRAG.
 **********************************************************************/
C_OUTLINE::C_OUTLINE (
//constructor
                                 //steps to copy
ICOORD startpt, DIR128 * new_steps,
inT16 length                     //length of loop
):start (startpt), offsets(NULL) {
  inT8 dirdiff;                  //direction difference
  DIR128 prevdir;                //previous direction
  DIR128 dir;                    //current direction
  DIR128 lastdir;                //dir of last step
  TBOX new_box;                   //easy bounding
  inT16 stepindex;               //index to step
  inT16 srcindex;                //source steps
  ICOORD pos;                    //current position

  pos = startpt;
  stepcount = length;            // No. of steps.
  ASSERT_HOST(length >= 0);
  steps = reinterpret_cast<uinT8*>(alloc_mem(step_mem()));  // Get memory.
  memset(steps, 0, step_mem());

  lastdir = new_steps[length - 1];
  prevdir = lastdir;
  for (stepindex = 0, srcindex = 0; srcindex < length;
  stepindex++, srcindex++) {
    new_box = TBOX (pos, pos);
    box += new_box;
                                 //copy steps
    dir = new_steps[srcindex];
    set_step(stepindex, dir);
    dirdiff = dir - prevdir;
    pos += step (stepindex);
    if ((dirdiff == 64 || dirdiff == -64) && stepindex > 0) {
      stepindex -= 2;            //cancel there-and-back
      prevdir = stepindex >= 0 ? step_dir (stepindex) : lastdir;
    }
    else
      prevdir = dir;
  }
  ASSERT_HOST (pos.x () == startpt.x () && pos.y () == startpt.y ());
  do {
    dirdiff = step_dir (stepindex - 1) - step_dir (0);
    if (dirdiff == 64 || dirdiff == -64) {
      start += step (0);
      stepindex -= 2;            //cancel there-and-back
      for (int i = 0; i < stepindex; ++i)
        set_step(i, step_dir(i + 1));
    }
  }
  while (stepindex > 1 && (dirdiff == 64 || dirdiff == -64));
  stepcount = stepindex;
  ASSERT_HOST (stepcount >= 4);
}
Пример #4
0
void C_OUTLINE::reverse() {  //reverse drection
  DIR128 halfturn = MODULUS / 2; //amount to shift
  DIR128 stepdir;                //direction of step
  inT16 stepindex;               //index to cstep
  inT16 farindex;                //index to other side
  inT16 halfsteps;               //half of stepcount

  halfsteps = (stepcount + 1) / 2;
  for (stepindex = 0; stepindex < halfsteps; stepindex++) {
    farindex = stepcount - stepindex - 1;
    stepdir = step_dir (stepindex);
    set_step (stepindex, step_dir (farindex) + halfturn);
    set_step (farindex, stepdir + halfturn);
  }
}
Пример #5
0
	int OUTLINE::winding_num(Point pt) const{
		Point vec = start_pos() - pt;
		Point step_vec;
		int cross_product;
		int count = 0;

		for (int i = 0; i < path_length(); ++i){
			step_vec = step_dir(i);
			if (vec.y <= 0 && vec.y + step_vec.y > 0){
				cross_product = vec.cross_product(step_vec);
				if (cross_product > 0) //ÓÒ±ßÏòÉÏ
					++count;
				else if (cross_product == 0)
					return INTERSECTING;
			}
			else if (vec.y > 0 && vec.y + step_vec.y <= 0){
				cross_product = vec.cross_product(step_vec);
				if (cross_product < 0) //ÓÒ±ßÏòÏÂ
					--count;
				else if (cross_product == 0)
					return INTERSECTING;
			}
			vec += step_vec;
		}
		return count;
	}
Пример #6
0
inT16 C_OUTLINE::turn_direction() const {  //winding number
  DIR128 prevdir;                //previous direction
  DIR128 dir;                    //current direction
  inT16 stepindex;               //index to cstep
  inT8 dirdiff;                  //direction difference
  inT16 count;                   //winding count

  if (stepcount == 0)
    return 128;
  count = 0;
  prevdir = step_dir (stepcount - 1);
  for (stepindex = 0; stepindex < stepcount; stepindex++) {
    dir = step_dir (stepindex);
    dirdiff = dir - prevdir;
    ASSERT_HOST (dirdiff == 0 || dirdiff == 32 || dirdiff == -32);
    count += dirdiff;
    prevdir = dir;
  }
  ASSERT_HOST (count == 128 || count == -128);
  return count;                  //winding number
}
Пример #7
0
	int OUTLINE::area() const{
		Point pos = start_pos();
		int total = 0;
		for (int i = 0; i < path_length(); ++i){
			DIR dir = step_dir(i);
			Point dir_vec = dir;
			if (dir_vec.x > 0)
				total += pos.y;
			else if (dir_vec.x < 0)
				total -= pos.y;
			pos += dir_vec;

		}
		return total;
	}
Пример #8
0
C_OUTLINE::C_OUTLINE(                     //constructor
                     C_OUTLINE *srcline,  //outline to
                     FCOORD rotation      //rotate
                    ) : offsets(NULL) {
  TBOX new_box;                   //easy bounding
  inT16 stepindex;               //index to step
  inT16 dirdiff;                 //direction change
  ICOORD pos;                    //current position
  ICOORD prevpos;                //previous dest point

  ICOORD destpos;                //destination point
  inT16 destindex;               //index to step
  DIR128 dir;                    //coded direction
  uinT8 new_step;

  stepcount = srcline->stepcount * 2;
  if (stepcount == 0) {
    steps = NULL;
    box = srcline->box;
    box.rotate(rotation);
    return;
  }
                                 //get memory
  steps = (uinT8 *) alloc_mem (step_mem());
  memset(steps, 0, step_mem());

  for (int iteration = 0; iteration < 2; ++iteration) {
    DIR128 round1 = iteration == 0 ? 32 : 0;
    DIR128 round2 = iteration != 0 ? 32 : 0;
    pos = srcline->start;
    prevpos = pos;
    prevpos.rotate (rotation);
    start = prevpos;
    box = TBOX (start, start);
    destindex = 0;
    for (stepindex = 0; stepindex < srcline->stepcount; stepindex++) {
      pos += srcline->step (stepindex);
      destpos = pos;
      destpos.rotate (rotation);
      //  tprintf("%i %i %i %i ", destpos.x(), destpos.y(), pos.x(), pos.y());
      while (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
        dir = DIR128 (FCOORD (destpos - prevpos));
        dir += 64;                 //turn to step style
        new_step = dir.get_dir ();
        //  tprintf(" %i\n", new_step);
        if (new_step & 31) {
          set_step(destindex++, dir + round1);
          prevpos += step(destindex - 1);
          if (destindex < 2
            || ((dirdiff =
            step_dir (destindex - 1) - step_dir (destindex - 2)) !=
            -64 && dirdiff != 64)) {
            set_step(destindex++, dir + round2);
            prevpos += step(destindex - 1);
          } else {
            prevpos -= step(destindex - 1);
            destindex--;
            prevpos -= step(destindex - 1);
            set_step(destindex - 1, dir + round2);
            prevpos += step(destindex - 1);
          }
        }
        else {
          set_step(destindex++, dir);
          prevpos += step(destindex - 1);
        }
        while (destindex >= 2 &&
               ((dirdiff =
                 step_dir (destindex - 1) - step_dir (destindex - 2)) == -64 ||
                dirdiff == 64)) {
          prevpos -= step(destindex - 1);
          prevpos -= step(destindex - 2);
          destindex -= 2;        // Forget u turn
        }
        //ASSERT_HOST(prevpos.x() == destpos.x() && prevpos.y() == destpos.y());
        new_box = TBOX (destpos, destpos);
        box += new_box;
      }
    }
    ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
    dirdiff = step_dir (destindex - 1) - step_dir (0);
    while ((dirdiff == 64 || dirdiff == -64) && destindex > 1) {
      start += step (0);
      destindex -= 2;
      for (int i = 0; i < destindex; ++i)
        set_step(i, step_dir(i + 1));
      dirdiff = step_dir (destindex - 1) - step_dir (0);
    }
    if (destindex >= 4)
      break;
  }
  ASSERT_HOST(destindex <= stepcount);
  stepcount = destindex;
  destpos = start;
  for (stepindex = 0; stepindex < stepcount; stepindex++) {
    destpos += step (stepindex);
  }
  ASSERT_HOST (destpos.x () == start.x () && destpos.y () == start.y ());
}