示例#1
0
文件: Quadrant.cpp 项目: asapnet/geos
/**
* Returns the quadrant of a directed line segment from p0 to p1.
*/
int Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1) {
	double dx=p1.x-p0.x;
	double dy=p1.y-p0.y;
	if (dx==0.0 && dy==0.0)
	{
		throw util::IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0.toString());
	}
	return quadrant(dx, dy);
}
示例#2
0
///////////////////////////////////////////////////////////////////////////////
/// @brief Finds the shortest path from start to any target in the list, avoiding units and walls.  A path will never be found if all targets are occupied or contains a wall.  Returns true if and only if a path was found.
///
/// @param path If the return value is true, path will contain the shortest path from start to the nearest target.
/// @param start Where pathing is to start from.
/// @param targetList A list of target destinations.
///////////////////////////////////////////////////////////////////////////////
bool baseAI::findPath(vector<Coordinate>& path,
                    const Coordinate start,
                    const vector<Coordinate> targetList)
{
  int dis[26][26];
  int via[26][26];
  bool success = false;
  bool changing = true;
  int newVal;
  static bool first = true;

  //via
  //    1
  // 2     0
  //    3

  if (start.x() < 0 || start.y() < 0 || start.x() > 25 || start.y() > 25)
  {
    cout << "Error: Path was called with a start coordinate that was out of bounds.";
    return false;
  }

  for (int i = 0; i < targetList.size(); i++)
  {
    if (targetList[i].x() < 0 || targetList[i].y() < 0 || targetList[i].x() > 25 || targetList[i].y() > 25)
    {
      cout << "Error: Path was called with a target coordinate that was out of bounds.";
      return false;
    }
  }

  if (first)
  {
    first = false;
    plotWalls();
  }

  plotUnits();

  for (int x = 0; x < 26; x++)
  {
    for (int y = 0; y < 26; y++)
    {
      dis[x][y] = 999;
      via[x][y] = -1;
    }
  }

  for (int i = 0; i < targetList.size(); i++)
  {
    if (!occupied[targetList[i].x()][targetList[i].y()] && !walled[targetList[i].x()][targetList[i].y()])
      dis[targetList[i].x()][targetList[i].y()] = 0;
  }

  while (changing)
  {
    changing = false;
    for (int x = 0; x < 26; x++)
    {
      for (int y = 0; y < 26; y++)
      {
        if (!walled[x][y] && (!occupied[x][y] || start == Coordinate(x,y)))
        {
          //newVal = dis[x][y];
          if (x > 0)
          {
            if (dis[x-1][y]+1 < dis[x][y])
            {
              dis[x][y] = dis[x-1][y]+1;
              via[x][y] = 2;
              changing = true;
            }
          }
          if (x < 25)
          {
            if (dis[x+1][y]+1 < dis[x][y])
            {
              dis[x][y] = dis[x+1][y]+1;
              via[x][y] = 0;
              changing = true;
            }
          }
          if (y > 0)
          {
            if (dis[x][y-1]+1 < dis[x][y])
            {
              dis[x][y] = dis[x][y-1]+1;
              via[x][y] = 3;
              changing = true;
            }
          }
          if (y < 25)
          {
            if (dis[x][y+1]+1 < dis[x][y])
            {
              dis[x][y] = dis[x][y+1]+1;
              via[x][y] = 1;
              changing = true;
            }
          }
        }
      }
    }
  }

  path.clear();

  Coordinate curPos(start.x(), start.y());

  if (via[start.x()][start.y()] == -1)
  {
    success = false;
  }
  else
  {
    success = true;
    while (dis[curPos.x()][curPos.y()] != 0)
    {
      switch (via[curPos.x()][curPos.y()])
      {
      case 0:
        curPos = curPos + Coordinate(1, 0);
      break;
      case 1:
        curPos = curPos + Coordinate(0, 1);
      break;
      case 2:
        curPos = curPos + Coordinate(-1, 0);
      break;
      case 3:
        curPos = curPos + Coordinate(0, -1);
      break;
      }
      path.push_back(curPos);
    }
  }
  return success;
}
示例#3
0
int main(int argc, char const *argv[])
{
    if (argc != 3 && argc != 4) {
        TERMINATE("%s\n%s\n%s\n%s\n", "Argumen tidak sesuai",
                "Cara kompilasi: g++ solver_checker.cpp -o solver_checker",
                "Cara pemakaian: ./solver_checker <file_input> <file_output> [<file_kamus>]",
                "                Jika <file_kamus> tidak ada, maka akan digunakan \"kamus.txt\".");
    }

    // Membuka berkas masukan dan keluaran
    FILE* fin = fopen(argv[1], "r");
    if (fin == NULL) {
        TERMINATE("Berkas masukan \"%s\" tidak ditemukan!\n", argv[1]);
    }

    FILE* fout = fopen(argv[2], "r");
    if (fout == NULL) {
        fclose(fin);
        TERMINATE("Berkas keluaran \"%s\" tidak ditemukan!\n", argv[2]);
    }

    if (argc == 4) {
        strcpy(buffer, argv[3]);
    } else {
        strcpy(buffer, DEFAULT_DICTIONARY_FILENAME);
    }
    FILE* fdict = fopen(buffer, "r");
    if (fdict == NULL) {
        fclose(fin);
        fclose(fout);
        TERMINATE("Berkas kamus \"%s\" tidak ditemukan!\n", buffer);
    }

    // Membaca seluruh kata pada kamus dan memasukkannya ke set dictionary
    set<string> dictionary;
    while (fscanf(fdict, "%s", buffer) == 1) {
        toUppercaseWord(buffer);

        // Memastikan format sesuai
        ASSERT(consistsOfEnglishAlphabets(buffer), "Kata \"%s\" pada kamus tidak valid!\n", buffer);

        // Memastikan kata tidak muncul dua kali
        ASSERT(!EXIST(buffer, dictionary), "Kata \"%s\" muncul dua kali pada kamus\n", buffer);

        dictionary.insert(buffer);
    }
    fclose(fdict);

    // Membaca seluruh kata, koordinat dan arah pada masukan dan memasukkannya ke inputWords
    vector<CrosswordWord> inputWords;
    int row, col;
    while (fscanf(fin, "%s%d%d%s", buffer, &row, &col, bufferDirection) == 4) {
        toUppercaseWord(buffer);
        toUppercaseWord(bufferDirection);

        // Memastikan format sesuai
        ASSERT(consistsOfEnglishAlphabetsOrDots(buffer), "Kata \"%s\" pada masukan tidak valid!\n",
                buffer);
        ASSERT(!(strcmp(bufferDirection, "MENDATAR") && strcmp(bufferDirection, "MENURUN")),
                "Arah \"%s\" tidak valid! (Seharusnya \"mendatar\" atau \"menurun\")\n",
                bufferDirection);

        inputWords.push_back(CrosswordWord(buffer, CrosswordWord::getDirection(bufferDirection),
                row, col));
    }
    fclose(fin);

    // Langsung berhenti saat masukan kosong
    ASSERT(!inputWords.empty(), "Tidak ada kata pada masukan!\n");

    // Membaca seluruh kata, koordinat dan arah pada keluaran dan memasukkannya ke outputWords
    vector<CrosswordWord> outputWords;
    while (fscanf(fout, "%s%d%d%s", buffer, &row, &col, bufferDirection) == 4) {
        toUppercaseWord(buffer);
        toUppercaseWord(bufferDirection);

        // Memastikan format sesuai
        ASSERT(consistsOfEnglishAlphabets(buffer), "Kata \"%s\" pada keluaran tidak valid!\n",
                buffer);
        ASSERT(!(strcmp(bufferDirection, "MENDATAR") && strcmp(bufferDirection, "MENURUN")),
                "Arah \"%s\" tidak valid! (Seharusnya \"mendatar\" atau \"menurun\")\n",
                bufferDirection);

        outputWords.push_back(CrosswordWord(buffer, CrosswordWord::getDirection(bufferDirection),
                row, col));
    }
    fclose(fout);

    // Langsung berhenti saat keluaran kosong
    ASSERT(!outputWords.empty(), "Tidak ada kata pada keluaran!\n");

    // Memasukkan seluruh kata ke dalam grid yang direpresentasikan oleh map sambil mendaftar
    // semua kontradiksi yang ada pada grid
    map<Coordinate, char> crosswordGrid;
    map<Coordinate, CrosswordWord> directionMapping[2];
    vector<Coordinate> contradictions;
    Coordinate topLeft, bottomRight;
    bool firstCharacter = true;

    for (vector<CrosswordWord>::iterator crosswordWord = inputWords.begin();
            crosswordWord != inputWords.end(); ++crosswordWord) {
        Coordinate position = crosswordWord->start;

        // Periksa apakah sudah ada kata pada koordinat dan arah yang sama
        ASSERT(!EXIST(position, directionMapping[crosswordWord->direction]),
                "Ada dua kata pada koordinat (%d, %d) %s\n", position.row, position.col,
                crosswordWord->direction == ACCROSS ? "mendatar" : "menurun");
        directionMapping[crosswordWord->direction][position] = *crosswordWord;

        // Masukkan tiap karakter ke map
        for (unsigned int i = 0; i < crosswordWord->word.length(); ++i) {
            char ch = crosswordWord->word[i];
            if (EXIST(position, crosswordGrid)) {
                if (crosswordGrid[position] != ch) {
                    crosswordGrid[position] = '?';
                    contradictions.push_back(position);
                }
            } else {
                crosswordGrid[position] = ch;
            }

            // Memperbarui batas crossword: topLeft dan bottomRight
            if (firstCharacter) {
                firstCharacter = false;
                topLeft = bottomRight = position;
            } else {
                if (position.row < topLeft.row) {
                    topLeft.row = position.row;
                }
                if (position.col < topLeft.col) {
                    topLeft.col = position.col;
                }
                if (position.row > bottomRight.row) {
                    bottomRight.row = position.row;
                }
                if (position.col > bottomRight.col) {
                    bottomRight.col = position.col;
                }
            }

            // Memajukan koordinat position sesuai dengan arah kata
            position.advance(crosswordWord->direction);
        }
    }

    // Cetak grid sebelum diisi
    printf("Teka-teki silang yang pada masukan:\n\n");
    printCrossword(crosswordGrid);

    // Jika ada kontradiksi, keluarkan daftarnya
    if (!contradictions.empty()) {
        string message = "Terdapat kontradiksi pada koordinat";
        for (int i = 0; i < contradictions.size(); ++i) {
            if (i == 0) {
                sprintf(buffer, " (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else if (i + 1 < contradictions.size()) {
                sprintf(buffer, ", (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else if (contradictions.size() == 2) {
                sprintf(buffer, " dan (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else {
                sprintf(buffer, ", dan (%d, %d)", contradictions[i].row, contradictions[i].col);
            }
            message += buffer;
        }
        TERMINATE("%s\n", message.c_str());
    }

    // Final check: cari kata baru yang terbentuk, atau cari kata yang tidak valid
    for (map<Coordinate, char>::iterator startIterator = crosswordGrid.begin();
            startIterator != crosswordGrid.end(); ++startIterator) {
        Coordinate start = startIterator->first;
        for (int direction = 0; direction < 2; ++direction) {
            Coordinate position = start;
            string word;
            while (EXIST(position, crosswordGrid)) {
                word.push_back(crosswordGrid[position]);
                position.advance(direction);
            }

            Coordinate previous = start - Coordinate::STEP[direction];
            // Periksa kalau pada koordinat dan arah ini ada kata pada map
            if (EXIST(start, directionMapping[direction])) {
                string originalWord = directionMapping[direction][start].word;

                // Kata tidak cocok
                ASSERT(word == originalWord,
                        "Pada koordinat (%d, %d) %s: Seharusnya \"%s\", tapi ditemukan \"%s\"\n",
                        start.row, start.col, direction == ACCROSS ? "mendatar" : "menurun",
                        originalWord.c_str(), word.c_str());
                // Kata diawali oleh huruf lain
                ASSERT(!EXIST(previous, crosswordGrid),
                        "Ditemukan huruf sebelum kata \"%s\", (%d, %d) %s\n",
                        originalWord.c_str(), start.row, start.col,
                        direction == ACCROSS ? "mendatar" : "menurun");
            } else {
                // Periksa kalau ada kata baru yang terbentuk
                ASSERT(EXIST(previous, crosswordGrid) || word.length() <= WORD_THRESHOLD,
                        "Ditemukan kata \"%s\" yang tidak ada pada masukan pada (%d, %d) %s\n",
                        word.c_str(), start.row, start.col,
                        direction == ACCROSS ? "mendatar" : "menurun");
            }
        }
    }

    // Sekarang, isi teka-teki silang tersebut dengan kata pada keluaran
    // Tiap kali ada kegagalan, simpan di issues.
    map<int, string> issues;
    set<string> usedWords;
    map<Coordinate, bool> finished[2];
    int totalSuccess = 0;
    for (vector<CrosswordWord>::iterator crosswordWord = outputWords.begin();
            crosswordWord != outputWords.end(); ++crosswordWord) {
        int i = crosswordWord - outputWords.begin();
        Coordinate position = crosswordWord->start;

        // Kata tidak ada pada kamus
        if (!EXIST(crosswordWord->word, dictionary)) {
            sprintf(buffer, "Kata \"%s\" tidak ada pada kamus", crosswordWord->word.c_str());
            issues[i] = buffer;
            continue;
        }
        // Kata yang sama telah dipakai
        if (EXIST(crosswordWord->word, usedWords)) {
            sprintf(buffer, "Kata \"%s\" telah digunakan sebelumnya", crosswordWord->word.c_str());
            issues[i] = buffer;
            // issue ini diperbolehkan untuk lanjut
        }
        // Kata tidak ada pada directionMapping
        if (!EXIST(position, directionMapping[crosswordWord->direction])) {
            sprintf(buffer, "Tidak ada yang harus diisi pada (%d, %d) %s", position.row,
                    position.col, crosswordWord->direction == ACCROSS ? "mendatar" : "menurun");
            issues[i] = buffer;
            continue;
        }
        // Kata sudah diselesaikan sebelumnya
        if (finished[crosswordWord->direction][position]) {
            sprintf(buffer, "Kata pada (%d, %d) %s sudah diisi sebelumnya", position.row,
                    position.col, crosswordWord->direction == ACCROSS ? "mendatar" : "menurun");
            issues[i] = buffer;
            continue;
        }

        // Mencoba untuk mengisi kata pada posisi dan arah ini
        CrosswordWord unknown = directionMapping[crosswordWord->direction][position];
        bool success = unknown.word.length() == crosswordWord->word.length();
        for (int j = 0; j < unknown.word.length() && success; ++j) {
            if (unknown.word[j] != '.' && unknown.word[j] != crosswordWord->word[j]) {
                success = false;
            }
        }
        if (!success) {
            sprintf(buffer, "Kata \"%s\" tidak bisa diiisi pada (%d, %d) %s",
                    crosswordWord->word.c_str(), position.row, position.col,
                    crosswordWord->direction == ACCROSS ? "mendatar" : "menurun" );
            issues[i] = buffer;
            continue;
        }

        // Berhasil!
        finished[crosswordWord->direction][position] = true;
        totalSuccess++;
        for (int j = 0; j < unknown.word.length() && success; ++j) {
            crosswordGrid[position] = crosswordWord->word[j];
            position.advance(crosswordWord->direction);
        }
    }

    // Keluarkan hasilnya
    printf("Teka-teki silang setelah diisi:\n\n");
    printCrossword(crosswordGrid);

    printf("Kata yang berhasil diisi : %d dari %d\n", totalSuccess, (int)inputWords.size());
    if (!issues.empty()) {
        printf("Ditemukan %d masalah pada keluaran :\n", (int)issues.size());
        for (map<int, string>::iterator it = issues.begin(); it != issues.end(); ++it) {
            printf("%3d. %s\n", it->first + 1, it->second.c_str());
        }
    }

    return 0;
}
示例#4
0
inline int  Coordinate::operator<(const Coordinate &rhs) const {
    if (x == rhs.GetX()) return y < rhs.GetY();
    else return x < rhs.GetX();
}
示例#5
0
void Coordinate::center(const Coordinate & coord){
    const double centerx = (coord.getRelativeX1() + coord.getRelativeX2())/2;
    const double centery = (coord.getRelativeY1() + coord.getRelativeY2())/2;
    
    set(centerx, centery, centerx, centery);
}
		//This will return a list of polygons that can be used to explicitly 
		//outline the bounding structure. This is being created for collision
		//debugging, and may not be appropriate for rendering complex arbitrary 
		//hulls due to many redundant shared verticies.
		PtrLineList GetShape(){
			//Create a wireframe for our AABB

			//Store the wires we've found
			PtrLineList result(new LineList);

			//We are finished when we run out of verticies to consider
			set<Coordinate> WorkingVerticies;
			set<Coordinate> WorkingVerticiesSwapBuffer;

			//add our first vertex as a seed

			WorkingVerticies.insert(Location);

			Coordinate CurrentV;
			Coordinate::iterator CVi;
			Coordinate PreviousV;

			//to iterate over our location and dimensions
			Coordinate::iterator Li;
			Coordinate::iterator Di;

			Line L;

			//When both vertex buffers are empty, we exit
			while(WorkingVerticies.size() > 0){

				//When one vertex buffer is empty, we swap the new one in its place
				while(WorkingVerticies.size() > 0){
					//(re)set our iterators
					Di = Dimensions.begin();
					Li = Location.begin();

					//begin processing the first vertex.
					CurrentV = PreviousV = *WorkingVerticies.begin();
					CVi = CurrentV.begin();

					//Go through our location dimension by dimension.
					while(CVi!=CurrentV.end()){
						//if this dimension has not been incremented to its extreme
						if(*CVi == *Li){
							//increment it to it's extreme
							*CVi = (*Li) + (*Di);
							//verticies in the swap buffer will be processed
							//in the next iterative pass.
							WorkingVerticiesSwapBuffer.insert(CurrentV);
							//Add our new line segment
							L.first = PreviousV;
							L.second = CurrentV;
							result->push_back(L);

							if(debug){
								Coordinate::iterator Ci = PreviousV.begin();
								while(Ci != PreviousV.end()){
									++Ci;
								}
								Ci = CurrentV.begin();
								while(Ci != CurrentV.end()){
									++Ci;
								}
							}

							//Undo our increment and move on
							*CVi = *Li;
						}
						++CVi;
						++Li;
						++Di;
					}

					//We are done processing this vertex. Remove it.
					WorkingVerticies.erase(WorkingVerticies.begin());
				}

				//Dump swap buffer into WorkingVerticies. if swap.size()>0, we iterate.
				WorkingVerticies = WorkingVerticiesSwapBuffer;
				WorkingVerticiesSwapBuffer.clear();
			}
			return result;
		}
示例#7
0
 inline Coordinate operator-(const Coordinate & coor, const Vector & vec) {
     return Coordinate(coor.getX() - vec.getDx(), coor.getY() - vec.getDy());
 }
mapnik::geometry::point<double> geowave_featureset::create_point(Point point)
{
    Coordinate coord = point.getCoordinate();
    return mapnik::geometry::point<double>(coord.x(), coord.y());
}
Coordinate ClippingService::calcIntersection(Coordinate cord1, Coordinate cord2, ViewWindow *window, int regionCode)
{
  double x, y;
  if (regionCode & TOP)
  {
    x = cord1.getx() + (cord2.getx() - cord1.getx()) * (window->getYwmax() -
        cord1.gety()) / (cord2.gety() - cord1.gety());
    y = window->getYwmax();
  }
  else if (regionCode & BOTTOM)
  {
    x = cord1.getx() + (cord2.getx() - cord1.getx()) * (window->getYwmin() -
        cord1.gety()) / (cord2.gety() - cord1.gety());
    y = window->getYwmin();
  }
  else if (regionCode & RIGHT)
  {
    y = cord1.gety() + (cord2.gety() - cord1.gety()) * (window->getXwmax() -
        cord1.getx()) / (cord2.getx() - cord1.getx());
    x = window->getXwmax();
  }
  else if (regionCode & LEFT)
  {
    y = cord1.gety() + (cord2.gety() - cord1.gety()) * (window->getXwmin() -
        cord1.getx()) / (cord2.getx() - cord1.getx());
    x = window->getXwmin();
  }

  return Coordinate(x, y);
}
示例#10
0
LatLon PlateCaree::crd2ll(const Coordinate &crd) const
{
    LatLon ll(crd.y() * 180.0 / M_PI, crd.x() * 180.0 / M_PI);
    return ll;
}
mapnik::geometry::polygon<double>  geowave_featureset::create_polygon(Polygon polygon)
{
    mapnik::geometry::polygon<double> polygon_out;
    
    // handle exterior ring
    {
        LineString geom = polygon.getExteriorRing();
        mapnik::geometry::linear_ring<double> linear_ring;
        for (int point_idx = geom.getNumPoints()-1; point_idx >= 0; --point_idx)
        {
            Coordinate coord = geom.getPointN(point_idx).getCoordinate();
            linear_ring.add_coord(coord.x(), coord.y());
        }
        if (geom.isClosed())
        {
            Coordinate coord = geom.getPointN(geom.getNumPoints()-1).getCoordinate();
            linear_ring.add_coord(coord.x(), coord.y());
        }
        polygon_out.set_exterior_ring(std::move(linear_ring));
    }

    // handle interior rings
    {
        for (int ring_idx = 0; ring_idx < polygon.getNumInteriorRing(); ++ring_idx)
        {
            LineString geom = polygon.getInteriorRingN(ring_idx);
            mapnik::geometry::linear_ring<double> linear_ring;
            for (int point_idx = geom.getNumPoints()-1; point_idx >= 0; --point_idx)
            {
                Coordinate coord = geom.getPointN(point_idx).getCoordinate();
                linear_ring.add_coord(coord.x(), coord.y());
            }
            if (geom.isClosed())
            {
                Coordinate coord = geom.getPointN(geom.getNumPoints()-1).getCoordinate();
                linear_ring.add_coord(coord.x(), coord.y());
            }
            polygon_out.add_hole(std::move(linear_ring));
        }
    }
    return polygon_out;
}
示例#12
0
  /**
   * @brief Applies registration of two points
   *
   * This method applies the registration of a left and right point set.  The
   * points sets may only have the left point defined.  This method determines
   * the valid geometry of the left point.  If the right point is not defined,
   * it uses the left geometry to determine the right point to register the
   * left point with.  If the right point is defined, it verifies the point has
   * valid geometry mapping in the right image.  All points and geometry must
   * fall within the boundaries of the image and be valid or the point is
   * deemed invalid.
   *
   * Once the points is validated, registration is applied to the two points
   * using the left point as truth (or the pattern chip) and the right point
   * (search chip) is loaded according to the geometry of the left chip.  An
   * affine transform is immediately applied in the Gruen algorithm to apply
   * the user supplied state of the affine and radiometric parameters.
   *
   * @author Kris Becker - 6/4/2011
   *
   * @param lpg
   * @param rpg
   * @param affrad
   *
   * @return SmtkPoint
   */
  SmtkPoint SmtkMatcher::Register(const PointGeometry &lpg,
                                  const PointGeometry &rpg,
                                  const AffineRadio &affrad) {

    // Validate object state
    validate();

    // Test if the left point is defined. This will throw an error if this
    // situation occurs
    if (!lpg.getPoint().isValid()) {
      QString mess = "Left point is not defined which is required";
      throw IException(IException::Programmer, mess, _FILEINFO_);
    }

   // First we need a lat,lon from the left image to find the same place in
    // the right image.
    Coordinate lpnt = lpg.getPoint();
    Coordinate lgeom = lpg.getGeometry();
    if (!lgeom.isValid()) {
      lgeom = getLatLon(lhCamera(), lpnt);
    }

    // Construct geometry and check validity
    PointGeometry left = PointGeometry(lpnt, lgeom);
    if (!left.isValid()) {
      m_offImage++;
      return ( SmtkPoint(PointPair(lpnt), PointPair(lgeom)) );
    }

    // Validate the right point
    Coordinate rpnt = rpg.getPoint();
    Coordinate rgeom = rpg.getGeometry();
    if ( !rpnt.isValid() ) {
      if (rgeom.isValid()) {
        rpnt = getLineSample(rhCamera(), rgeom);
      }
      else {
        rpnt = getLineSample(rhCamera(), lgeom);
        rgeom = lgeom;
      }
    }
    else if (!rgeom.isValid() ){
      rgeom = getLatLon(rhCamera(), rpnt);
    }

    //  Construct and for good right geometry
    PointGeometry right = PointGeometry(rpnt, rgeom);
    if (!right.isValid()) {
      m_spiceErr++;
      return (SmtkPoint(PointPair(lpnt, rpnt), PointPair(lgeom, rgeom)));
    }

    try {
      // These calls are computationally expensive... can we fix it?
      m_gruen->PatternChip()->TackCube(lpnt.getSample(), lpnt.getLine());
      m_gruen->PatternChip()->Load(*m_lhCube);
      m_gruen->SearchChip()->TackCube(rpnt.getSample(), rpnt.getLine());
      m_gruen->SearchChip()->Load(*m_rhCube, *m_gruen->PatternChip(),
                                  *m_lhCube);
    }
    catch (IException &) {
      m_offImage++;  // Failure to load is assumed an offimage error
      return (SmtkPoint(PointPair(lpnt,rpnt), PointPair(lgeom,rgeom)));
    }

    // Register the points with incoming affine/radiometric parameters
    m_gruen->setAffineRadio(affrad);
    return (makeRegisteredPoint(left, right, m_gruen.get()));
  }
示例#13
0
文件: field.cpp 项目: srzs/SeaBattle
Coordinate Coordinate::operator-(const Coordinate &other) const
{
    return {this->x() - other.x(), this->y() - other.y()};
}
示例#14
0
bool Piece::outOfBounds(Coordinate Coord)
{
    if (Coord.getX() >= 0 && Coord.getX() <= 7 && Coord.getY() >= 0 && Coord.getY() <= 7)
        return false;
    return true;
}
示例#15
0
int main()
{
    unsigned row, column, i;
    unsigned N_Losses, E_Losses;
    Coordinate* testSize;
    Coordinate* tempCoordinate;
    string testName1, testName2, loserName;
    Chooser* testChooser;
    Player* testNovice;
    Player* testExpert;
    Attack* testAttack;

    srand(time(NULL));
    N_Losses = 0;
    E_Losses = 0;

    testName1 = "Pugwash";
    testName2 = "Roger";

    testSize = new Coordinate;
    testSize->init_SpecificCoordinate(10, 10);

    testChooser = new Random;

    for(i=0; i<1000; i++)
    {
        testNovice = new Novice(testSize, testName1);
        testExpert = new Expert(testSize, testName2);
        testNovice->setupFleet();
        testExpert->setupFleet();
        testNovice->addOpponent(testExpert);
        testExpert->addOpponent(testNovice);

        do
        {
            testAttack = testNovice->getAttack();

            tempCoordinate = testAttack->getTargetCoordinate();
            row = tempCoordinate->getCoordinateRow();
            column = tempCoordinate->getCoordinateColumn();

            cout << "Attack on " << testAttack->getTargetName() << " at row " << row << " column " << column << endl;

            testExpert->processAttack(testAttack);
            testNovice->setAttackResult(testAttack);

            if(testAttack->getFleetDestroyed() == false)
            {
                testAttack = testExpert->getAttack();

                tempCoordinate = testAttack->getTargetCoordinate();
                row = tempCoordinate->getCoordinateRow();
                column = tempCoordinate->getCoordinateColumn();

                cout << "Attack on " << testAttack->getTargetName() << " at row " << row << " column " << column << endl;

                testNovice->processAttack(testAttack);
                testExpert->setAttackResult(testAttack);
            }
        }while(testAttack->getFleetDestroyed() == false);

        loserName = testAttack->getTargetName();
        if(loserName.compare(testName1) == 0)
        {
            N_Losses++;
        }
        else
        {
            E_Losses++;
        }
        cout << testAttack->getTargetName() << " has been defeated!" << endl;
        testAttack->uninit_Attack();
        delete testAttack;
        delete testNovice;
        delete testExpert;
    }
    cout << testName1 << " lost " << N_Losses << " " << testName2 << " lost " << E_Losses << endl;
    cin.get();
}
示例#16
0
  void DimensionsTest::RunTests()
  {
    Coordinate zero; // [0];
    zero.push_back(0);

    Coordinate one_two; // [1,2]
    one_two.push_back(1);
    one_two.push_back(2);

    Coordinate three_four; // [3,4]
    three_four.push_back(3);
    three_four.push_back(4);
    

    {
      // empty dimensions (unspecified)
      Dimensions d;
      TEST(d.isUnspecified());
      TEST(d.isValid());
      TEST(!d.isDontcare());
      SHOULDFAIL(d.getCount());
      SHOULDFAIL(d.getDimension(0));
      TESTEQUAL("[unspecified]", d.toString());
      SHOULDFAIL(d.getIndex(one_two));
      SHOULDFAIL(d.getCount());
      SHOULDFAIL(d.getDimension(0));
      TESTEQUAL((unsigned int)0, d.getDimensionCount());
    }

    {
      // dontcare dimensions [0]
      Dimensions d;
      d.push_back(0);
      TEST(!d.isUnspecified());
      TEST(d.isDontcare());
      TEST(d.isValid());
      TESTEQUAL("[dontcare]", d.toString());
      SHOULDFAIL(d.getIndex(zero));
      SHOULDFAIL(d.getCount());
      TESTEQUAL((unsigned int)0, d.getDimension(0));
      TESTEQUAL((unsigned int)1, d.getDimensionCount());
    }


    {
      // invalid dimensions
      Dimensions d;
      d.push_back(1);
      d.push_back(0);
      TEST(!d.isUnspecified());
      TEST(!d.isDontcare());
      TEST(!d.isValid());
      TESTEQUAL("[1 0] (invalid)", d.toString());
      SHOULDFAIL(d.getIndex(one_two));
      SHOULDFAIL(d.getCount());
      TESTEQUAL((unsigned int)1, d.getDimension(0));
      TESTEQUAL((unsigned int)0, d.getDimension(1));
      SHOULDFAIL(d.getDimension(2));
      TESTEQUAL((unsigned int)2, d.getDimensionCount());
    }

    {
      // valid dimensions [2,3]
      // two rows, three columns
      Dimensions d;
      d.push_back(2);
      d.push_back(3);
      TEST(!d.isUnspecified());
      TEST(!d.isDontcare());
      TEST(d.isValid());
      TESTEQUAL("[2 3]", d.toString());
      TESTEQUAL((unsigned int)2, d.getDimension(0));
      TESTEQUAL((unsigned int)3, d.getDimension(1));
      SHOULDFAIL(d.getDimension(2));
      TESTEQUAL((unsigned int)6, d.getCount());
      TESTEQUAL((unsigned int)5, d.getIndex(one_two));
      TESTEQUAL((unsigned int)2, d.getDimensionCount());
    }

    {
      //check a two dimensional matrix for proper x-major ordering
      std::vector<size_t> x;
      x.push_back(4);
      x.push_back(5);
      Dimensions d(x);
      size_t testDim1 = 4;
      size_t testDim2 = 5;
      for(size_t i = 0; i < testDim1; i++)
      {
        for(size_t j = 0; j < testDim2; j++)
        {
          Coordinate testCoordinate;
          testCoordinate.push_back(i);
          testCoordinate.push_back(j);

          TESTEQUAL(i+j*testDim1, d.getIndex(testCoordinate));
          TESTEQUAL(vecToString(testCoordinate),
                    vecToString(d.getCoordinate(i+j*testDim1)));
        }
      }
    }

    {
      //check a three dimensional matrix for proper x-major ordering
      std::vector<size_t> x;
      x.push_back(3);
      x.push_back(4);
      x.push_back(5);
      Dimensions d(x);
      size_t testDim1 = 3;
      size_t testDim2 = 4;
      size_t testDim3 = 5;
      for(size_t i = 0; i < testDim1; i++)
      {
        for(size_t j = 0; j < testDim2; j++)
        {
          for(size_t k = 0; k < testDim3; k++)
          {
            Coordinate testCoordinate;
            testCoordinate.push_back(i);
            testCoordinate.push_back(j);
            testCoordinate.push_back(k);

            TESTEQUAL(i +
                      j*testDim1 +
                      k*testDim1*testDim2, d.getIndex(testCoordinate));

            TESTEQUAL(vecToString(testCoordinate),
                      vecToString(d.getCoordinate(i +
                                                  j*testDim1 +
                                                  k*testDim1*testDim2)));
          }
        }
      }
    }

    { 
      // alternate constructor
      std::vector<size_t> x;
      x.push_back(2);
      x.push_back(5);
      Dimensions d(x);
      TEST(!d.isUnspecified());
      TEST(!d.isDontcare());
      TEST(d.isValid());
      
      TESTEQUAL((unsigned int)2, d.getDimension(0));
      TESTEQUAL((unsigned int)5, d.getDimension(1));
      SHOULDFAIL(d.getDimension(2));
      TESTEQUAL((unsigned int)2, d.getDimensionCount());
    }

  } // RunTests()
示例#17
0
		//when we call this, we must be sure the object is 3d
		void Draw3DQuads(){
			Coordinate::iterator Di = Dimensions.begin();
			Coordinate::iterator Li = Location.begin();

			glBegin(GL_QUADS);
			//front
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]);
			//top
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]+Di[2]);
			//bottom
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]+Di[2]);
			//back
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]+Di[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]+Di[2]);
			//left
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]+Di[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0],Li[1],Li[2]);
			//right
			glTexCoord2f(0.0,0.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]);
			glTexCoord2f(0.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]);
			glTexCoord2f(1.0,1.0);
			glVertex3f(Li[0]+Di[0],Li[1]+Di[1],Li[2]+Di[2]);
			glTexCoord2f(1.0,0.0);
			glVertex3f(Li[0]+Di[0],Li[1],Li[2]+Di[2]);
			glEnd();
		}
示例#18
0
int main(int argc, char const *argv[])
{
    if (argc != 3) {
        TERMINATE("%s\n%s\n%s\n", "Argumen tidak sesuai",
                "Cara kompilasi: g++ generator_checker.cpp -o generator_checker",
                "Cara pemakaian: ./generator_checker <file_input> <file_output>");
    }

    // Membuka berkas masukan dan keluaran
    FILE* fin = fopen(argv[1], "r");
    if (fin == NULL) {
        TERMINATE("Berkas masukan \"%s\" tidak ditemukan!\n", argv[1]);
    }

    FILE* fout = fopen(argv[2], "r");
    if (fout == NULL) {
        fclose(fin);
        TERMINATE("Berkas keluaran \"%s\" tidak ditemukan!\n", argv[2]);
    }

    // Membaca seluruh kata pada berkas masukan dan memasukkannya ke inputWords
    set<string> inputWords;
    while (fscanf(fin, "%s", buffer) == 1) {
        toUppercaseWord(buffer);

        // Memastikan format sesuai
        ASSERT(consistsOfEnglishAlphabets(buffer), "Kata \"%s\" pada masukan tidak valid!\n",
                buffer);

        // Langsung keluar jika menemukan kata yang ada dua kali pada masukan
        if (EXIST(buffer, inputWords)) {
            fclose(fin);
            TERMINATE("Kata %s muncul dua kali pada masukan!\n", buffer);
        }

        inputWords.insert(buffer);
    }
    fclose(fin);

    // Membaca seluruh kata, koordinat dan arah pada keluaran dan memasukkannya ke outputWords
    vector<CrosswordWord> outputWords;
    set<string> exsistedOutputWords;
    int row, col;
    while (fscanf(fout, "%s%d%d%s", buffer, &row, &col, bufferDirection) == 4) {
        toUppercaseWord(buffer);
        toUppercaseWord(bufferDirection);

        // Memastikan format sesuai
        ASSERT(consistsOfEnglishAlphabets(buffer), "Kata \"%s\" pada keluaran tidak valid!\n",
                buffer);
        ASSERT(!(strcmp(bufferDirection, "MENDATAR") && strcmp(bufferDirection, "MENURUN")),
                "Arah \"%s\" tidak valid! (Seharusnya \"mendatar\" atau \"menurun\")\n",
                bufferDirection);

        // Langsung keluar jika menemukan kata yang tidak ada pada masukan, atau muncul dua kali
        // pada keluaran
        if (!EXIST(buffer, inputWords)) {
            fclose(fout);
            TERMINATE("Kata %s tidak ditemukan pada masukan!\n", buffer);
        }
        if (EXIST(buffer, exsistedOutputWords)) {
            fclose(fout);
            TERMINATE("Kata %s muncul dua kali pada keluaran!\n", buffer);
        }

        outputWords.push_back(CrosswordWord(buffer, CrosswordWord::getDirection(bufferDirection),
                row, col));
        exsistedOutputWords.insert(buffer);
    }
    fclose(fout);

    // Langsung berhenti saat keluaran kosong
    ASSERT(!outputWords.empty(), "Tidak ada kata pada keluaran!\n");

    // Memasukkan seluruh kata ke dalam grid yang direpresentasikan oleh map sambil mendaftar
    // semua kontradiksi yang ada pada grid
    map<Coordinate, char> crosswordGrid;
    map<Coordinate, CrosswordWord> directionMapping[2];
    vector<Coordinate> contradictions;

    for (vector<CrosswordWord>::iterator crosswordWord = outputWords.begin();
            crosswordWord != outputWords.end(); ++crosswordWord) {
        Coordinate position = crosswordWord->start;

        // Periksa apakah sudah ada kata pada koordinat dan arah yang sama
        ASSERT(!EXIST(position, directionMapping[crosswordWord->direction]),
                "Ada dua kata pada koordinat (%d, %d) %s\n", position.row, position.col,
                crosswordWord->direction == ACCROSS ? "mendatar" : "menurun");
        directionMapping[crosswordWord->direction][position] = *crosswordWord;

        // Masukkan tiap karakter ke map
        for (unsigned int i = 0; i < crosswordWord->word.length(); ++i) {
            char ch = crosswordWord->word[i];
            if (EXIST(position, crosswordGrid)) {
                if (crosswordGrid[position] != ch) {
                    crosswordGrid[position] = '?';
                    contradictions.push_back(position);
                }
            } else {
                crosswordGrid[position] = ch;
            }

            // Memajukan koordinat position sesuai dengan arah kata
            position.advance(crosswordWord->direction);
        }
    }

    // Cetak grid
    printf("Teka-teki silang yang terbentuk:\n\n");
    printCrossword(crosswordGrid);

    // Jika ada kontradiksi, keluarkan daftarnya
    if (!contradictions.empty()) {
        string message = "Terdapat kontradiksi pada koordinat";
        for (int i = 0; i < contradictions.size(); ++i) {
            if (i == 0) {
                sprintf(buffer, " (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else if (i + 1 < contradictions.size()) {
                sprintf(buffer, ", (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else if (contradictions.size() == 2) {
                sprintf(buffer, " dan (%d, %d)", contradictions[i].row, contradictions[i].col);
            } else {
                sprintf(buffer, ", dan (%d, %d)", contradictions[i].row, contradictions[i].col);
            }
            message += buffer;
        }
        TERMINATE("%s\n", message.c_str());
    }

    // Final check: cari kata baru yang terbentuk, atau cari kata yang tidak valid
    for (map<Coordinate, char>::iterator startIterator = crosswordGrid.begin();
            startIterator != crosswordGrid.end(); ++startIterator) {
        Coordinate start = startIterator->first;
        for (int direction = 0; direction < 2; ++direction) {
            Coordinate position = start;
            string word;
            while (EXIST(position, crosswordGrid)) {
                word.push_back(crosswordGrid[position]);
                position.advance(direction);
            }

            Coordinate previous = start - Coordinate::STEP[direction];
            // Periksa kalau pada koordinat dan arah ini ada kata pada map
            if (EXIST(start, directionMapping[direction])) {
                string originalWord = directionMapping[direction][start].word;

                // Kata tidak cocok
                ASSERT(word == originalWord,
                        "Pada koordinat (%d, %d) %s: Seharusnya \"%s\", tapi ditemukan \"%s\"\n",
                        start.row, start.col, direction == ACCROSS ? "mendatar" : "menurun",
                        originalWord.c_str(), word.c_str());
                // Kata diawali oleh huruf lain
                ASSERT(!EXIST(previous, crosswordGrid),
                        "Ditemukan huruf sebelum kata \"%s\", (%d, %d) %s\n",
                        originalWord.c_str(), start.row, start.col,
                        direction == ACCROSS ? "mendatar" : "menurun");
            } else {
                // Periksa kalau ada kata baru yang terbentuk
                ASSERT(EXIST(previous, crosswordGrid) || word.length() <= WORD_THRESHOLD,
                        "Ditemukan kata \"%s\" yang tidak ada pada masukan pada (%d, %d) %s\n",
                        word.c_str(), start.row, start.col,
                        direction == ACCROSS ? "mendatar" : "menurun");
            }
        }
    }

    // Setelah semua valid, keluarkan metrik penilaian
    printf("Teka-teki silang di atas valid!\n\n");

    // Keluarkan banyak kata yang berhasil dipakai
    printf("1. Kata yang terpakai                : %d dari %d\n",
            (int)outputWords.size(), (int)inputWords.size());

    // Keluarkan "keterhubungan" dalam bentuk banyak komponen graf yang ada
    // Teknik flood-fill akan digunakan, dengan menggunakan struktur data stack
    int numComponent = 0;
    map<Coordinate, int> visited;
    for (map<Coordinate, char>::iterator startIterator = crosswordGrid.begin();
            startIterator != crosswordGrid.end(); ++startIterator) {
        if (visited[startIterator->first]) {
            continue;
        }
        vector<Coordinate> stack;
        stack.push_back(startIterator->first);
        visited[stack.back()] = 1;
        while (!stack.empty()) {
            Coordinate top = stack.back(), temp;
            stack.pop_back();

            temp = top - Coordinate::STEP[0];
            if (!visited[temp] && EXIST(temp, crosswordGrid)) {
                stack.push_back(temp);
                visited[temp] = 1;
            }
            temp = top + Coordinate::STEP[0];
            if (!visited[temp] && EXIST(temp, crosswordGrid)) {
                stack.push_back(temp);
                visited[temp] = 1;
            }
            temp = top - Coordinate::STEP[1];
            if (!visited[temp] && EXIST(temp, crosswordGrid)) {
                stack.push_back(temp);
                visited[temp] = 1;
            }
            temp = top + Coordinate::STEP[1];
            if (!visited[temp] && EXIST(temp, crosswordGrid)) {
                stack.push_back(temp);
                visited[temp] = 1;
            }
        }
        numComponent++;
    }
    printf("2. Komponen terhubung yang terbentuk : %d\n", numComponent);

    // Keluarkan ukuran teka-teki silang
    Coordinate topLeft, bottomRight;
    getCrosswordGridBounds(crosswordGrid, &topLeft, &bottomRight);
    printf("3. Ukuran teka-teki silang           : %d baris x %d kolom = %d kotak\n",
        bottomRight.row - topLeft.row + 1, bottomRight.col - topLeft.col + 1,
        (bottomRight.row - topLeft.row + 1) * (bottomRight.col - topLeft.col + 1));
    printf("   Banyak kotak yang terpakai        : %d kotak\n", (int)crosswordGrid.size());

    return 0;
}
示例#19
0
//==========================================================================================================
// moment_arm = dl/dtheta, definition using inexact peturbation technique
//==========================================================================================================
double computeMomentArmFromDefinition(const SimTK::State &s, const GeometryPath &path, const Coordinate &coord)
{
    using namespace SimTK;

    //Compute r = dl/dtheta
    SimTK::State s_ma = s;
    coord.setClamped(s_ma, false);
    coord.setLocked(s_ma, false);
    double theta = coord.getValue(s);
    double dtheta = 0.1*integ_accuracy;
    
    // Compute length 1 
    coord.setValue(s_ma, theta-dtheta, false);

    // satisfy contraints using project since we are close to the solution
    coord.getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Position);
    coord.getModel().getMultibodySystem().projectQ(s_ma, 1e-8);

    double theta1 = coord.getValue(s_ma);
    coord.getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Position);

    double len1 = path.getLength(s_ma);

    // Compute length 2
    coord.setValue(s_ma, theta+dtheta, false);

    // satisfy contraints using project since we are close to the solution
    coord.getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Position);
    coord.getModel().getMultibodySystem().projectQ(s_ma, 1e-8);

    double theta2 = coord.getValue(s_ma);
    coord.getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Position);

    double len2 = path.getLength(s_ma);

    return (len1-len2)/(theta2-theta1);
}
示例#20
0
void KMLState::write(ostream& out, const Coordinate& c, double altitude) const
{
    out << c.getLongitude().getAngle() << "," << c.getLatitude().getAngle() << "," << altitude;
}
示例#21
0
void Force::applyGeneralizedForce(const SimTK::State &s, const Coordinate &aCoord,
                                  double aForce, Vector &mobilityForces) const
{
    _model->getMatterSubsystem().addInMobilityForce(s, SimTK::MobilizedBodyIndex(aCoord.getBodyIndex()),
            SimTK::MobilizerUIndex(aCoord.getMobilizerQIndex()), aForce, mobilityForces);
}
示例#22
0
double Ellipse::getEllipseAngle(const Coordinate& coord) const {
    Coordinate offset = coord - _center;
    Coordinate point = offset.rotate(-_majorP.angle());
    return atan2(point.y() * _majorP.magnitude(), point.x() * _minorRadius);
}
/*********************************************************************************
Solve for moment arm, r = d(path_length)/d(theta)

Ideally we want to compute r without perturbing theta values and recomputing
lengths because it is inexact, very sensitive to perturbations that may cause a 
path (via) point to appear or disappear, and inefficient to recompute lengths, 
especially for complex paths involving wrapping.

Refer to Moment-arm Theory document by Michael Sherman for details.

**********************************************************************************/
double MomentArmSolver::solve(const State &s, const Coordinate &aCoord,
							  const Array<PointForceDirection *> &pfds)
{
	//const clock_t start = clock();

	//Local modifiable copy of the state
	_stateCopy.updQ() = s.getQ();
	_stateCopy.updU() = s.getU();
	State& s_ma = _stateCopy;

	//const clock_t copyT = clock();
	//cout << "MomentArmSolver::solve State copy time:" << 1000*(copyT-start)/CLOCKS_PER_SEC << "ms\n" <<endl;

	getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Instance);

	aCoord.setLocked(s_ma, false);

	double angle = aCoord.getValue(s_ma);	

	//const clock_t init = clock();
	//cout << "MomentArmSolver::solve realize instance in:" << 1000*(init-copyT)/CLOCKS_PER_SEC << "ms\n" <<endl;


	// Calculate coupling matrix C to determine the influence of other coordinates 
	// (mobilities) on the coordinate of interest due to constraints

    s_ma.updU() = 0;
	// Light-up speed of coordinate of interest and see how other coordinates
	// affected by constraints respond
    aCoord.setSpeedValue(s_ma, 1);

	getModel().getMultibodySystem().realize(s_ma, SimTK::Stage::Velocity);


    // Satisfy all the velocity constraints.
    getModel().getMultibodySystem().projectU(s_ma, 1e-10);
	
	
	// Now calculate C. by checking how speeds of other coordinates change
	// normalized by how much the speed of the coordinate of interest changed 
    _coupling = s_ma.getU() / aCoord.getSpeedValue(s_ma);

	//const clock_t computeC = clock();
	//cout << "MomentArmSolver::solve compute C time:" << 1000*(computeC-init)/CLOCKS_PER_SEC << "ms\n" <<endl;


	angle = aCoord.getValue(s_ma);

	// Reset speeds to zero
    s_ma.updU() = 0;
	
			
	// Apply body forces along the geometry described by pfds due to a tension of 1N
	for(int i=0; i < pfds.getSize(); i++) {
		getModel().getMatterSubsystem().addInStationForce(s_ma, SimTK::MobilizedBodyIndex(pfds[i]->body().getIndex()), 
												   pfds[i]->point(), pfds[i]->direction(), _bodyForces);
	}

	// Convert body spatial forces F to equivalent mobility forces f based on 
    // geometry (no dynamics required): f = ~J(q) * F.
	getModel().getMultibodySystem().getMatterSubsystem()
        .multiplyBySystemJacobianTranspose(s_ma, _bodyForces, _generalizedForces);

	//const clock_t torqueT = clock();;
	//cout << "MomentArmSolver::solve  compute effective torque in:" << 1000*(torqueT-computeC)/CLOCKS_PER_SEC << "ms\n" <<endl;

	// Moment-arm is the effective torque (since tension is 1) at the 
    // coordinate of interest taking into account the generalized forces also 
    // acting on other coordinates that are coupled via constraint.
	return ~_coupling*_generalizedForces;
}
示例#24
0
//! [0]
QDebug operator<<(QDebug dbg, const Coordinate &c)
{
    dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";
    
    return dbg.space();
}
示例#25
0
///////////////////////////////////////////////////////////////////////////////
/// @brief Queues an attack order for a unit. Reduces the unit's action count by 1
///
/// @param attackWith The unit that will attack
/// @param attackCoord The location to attack
/////////////////////////////////////////////////////////////////////////////// 
void baseAI::Attack(Unit& attackWith, const Coordinate& attackCoord)
{
   sout.str("");
   
   //Convert to s-expression
   sout << "(game-attack " << attackWith.id() << " " << attackCoord.x() << " " << attackCoord.y() << ")";
   myOrder.s_expression = sout.str();
   
   orders.push(myOrder);
   
   //Update unit actions
   attackWith.setActions(attackWith.actions()-1);
   attackWith.setMoves(0);
   
   //Update the official unit also
   for(unsigned int i=0; i < units.size(); ++i)
   {
      if(units[i].id() == attackWith.id())
      {
         //Make sure we weren't given a reference to the unit in the unit list...
         if(&units[i] != &attackWith)
         {
            units[i].setActions(units[i].actions()-1);
            units[i].setMoves(0);
         }
      }
   }
   
   //Perform attack/heal on units at the location
   bool healed = false;
   for(unsigned int i=0; i < units.size(); i++)
   {
      if(units[i].location() == attackCoord)
      {
         //Friendly - Heal!
         if(units[i].owner() == me.id())
         {
            healed = true;
            units[i].setCurHealth( units[i].curHealth() + attackWith.healPower());
         }
         
         //Enemy unit - attack!
         else
         {
            units[i].setCurHealth( units[i].curHealth() - attackWith.attackPower());
         }
      }
   }
   
   //If the unit didn't heal, he can splash
   if(!healed)
   {
      //Do splash!
      vector<Unit*> splashed;
      
      for(unsigned int i=0; i < units.size(); ++i)
      {
         //Find units within splash radius of 1, but not at attackCoord
         if(units[i].owner() != me.id() && 
         units[i].distanceTo(attackCoord) == 1)
         {
            splashed.push_back(&units[i]);
         }
      }
      for(unsigned int i=0; i < splashed.size(); ++i)
      {
         //Damage the units that are splashed
         splashed[i]->setCurHealth( splashed[i]->curHealth() - attackWith.splashDamage());
      }
   }
   
   return;
}
	bool equals(const Coordinate& p0, const Coordinate& p1,
	            double distanceTolerance)
        {
                return p0.distance(p1) <= distanceTolerance;
        }
示例#27
0
/**\brief Draws the Effect
 */
void Effect::Draw( void ) {
	Coordinate pos = GetWorldPosition();
	visual->Draw( pos.GetScreenX(), pos.GetScreenY(), this->GetAngle());
}
示例#28
0
文件: World.cpp 项目: jefe78/saiph
Tile World::shortestPath(const Coordinate& target) {
	/* returns a "fake" Tile with data for shortest path from player to target */
	if (target.level() < 0 || target.level() >= (int) _levels.size())
		return Tile(); // outside map
	else if (target.level() == Saiph::position().level())
		return _levels[Saiph::position().level()].tile(target); // target on same level

	int pivot = -1;
	int level_count = 1;
	int level_queue[_levels.size()];
	level_queue[0] = Saiph::position().level();
	bool level_added[_levels.size()];
	for (int a = 0; a < (int) _levels.size(); ++a)
		level_added[a] = false;
	level_added[Saiph::position().level()] = true;
	Tile level_tile[_levels.size()];
	level_tile[Saiph::position().level()] = shortestPath(Saiph::position());
	Debug::pathing() << "Trying to find path to " << target << endl;
	while (++pivot < level_count) {
		/* check if target is on level */
		if (level_queue[pivot] == target.level()) {
			Tile& tile = _levels[level_queue[pivot]].tile(target);
			if (tile.cost() == UNREACHABLE)
				continue;
			else if (tile.cost() == UNPASSABLE && tile.distance() > 1)
				continue;
			/* gotta modify this tile a bit since it's on another level */
			level_tile[level_queue[pivot]].updatePath(level_tile[level_queue[pivot]].direction(), tile.distance() + level_tile[level_queue[pivot]].distance() + 1, tile.cost() + level_tile[level_queue[pivot]].cost() + 1);
			Debug::pathing() << "Found " << target << " " << level_tile[level_queue[pivot]].distance() << " tiles away, first checkpoint is " << level_tile[level_queue[pivot]].coordinate() << endl;
			return level_tile[level_queue[pivot]];
		}
		/* path to upstairs on level */
		for (map<Point, int>::const_iterator s = _levels[level_queue[pivot]].symbols((unsigned char) STAIRS_UP).begin(); s != _levels[level_queue[pivot]].symbols((unsigned char) STAIRS_UP).end(); ++s) {
			if (s->second == UNKNOWN_SYMBOL_VALUE)
				continue; // we don't know where these stairs lead
			else if (level_added[s->second])
				continue; // already added this level
			Tile& tile = _levels[level_queue[pivot]].tile(s->first);
			if (tile.cost() >= UNPASSABLE)
				continue;
			Debug::pathing() << "Following upstairs on " << tile.coordinate() << " (" << _levels[level_queue[pivot]].name() << ") leading to level " << s->second << " (" << _levels[s->second].name() << ")" << endl;
			/* we know where these stairs lead, add the level to the queue */
			level_added[s->second] = true;
			level_queue[level_count++] = s->second;
			if (pivot == 0) {
				/* pathing to upstairs on level we're standing on */
				level_tile[s->second] = tile;
				if (tile.direction() == NOWHERE)
					level_tile[s->second].direction(UP);
			} else {
				/* pathing to upstairs on another level */
				level_tile[s->second] = level_tile[level_queue[pivot]];
				level_tile[s->second].updatePath(level_tile[s->second].direction(), level_tile[s->second].distance() + tile.distance() + 1, level_tile[s->second].cost() + tile.cost() + 1);
			}
		}
		/* path to downstairs on level */
		for (map<Point, int>::const_iterator s = _levels[level_queue[pivot]].symbols((unsigned char) STAIRS_DOWN).begin(); s != _levels[level_queue[pivot]].symbols((unsigned char) STAIRS_DOWN).end(); ++s) {
			if (s->second == UNKNOWN_SYMBOL_VALUE)
				continue; // we don't know where these stairs lead
			else if (level_added[s->second])
				continue; // already added this level
			Tile& tile = _levels[level_queue[pivot]].tile(s->first);
			if (tile.cost() >= UNPASSABLE)
				continue;
			Debug::pathing() << "Following downstairs on " << tile.coordinate() << " (" << _levels[level_queue[pivot]].name() << ") leading to level " << s->second << " (" << _levels[s->second].name() << ")" << endl;
			/* we know where these stairs lead, add the level to the queue */
			level_added[s->second] = true;
			level_queue[level_count++] = s->second;
			if (pivot == 0) {
				/* pathing to downstairs on level we're standing on */
				level_tile[s->second] = tile;
				if (tile.direction() == NOWHERE)
					level_tile[s->second].direction(DOWN);
			} else {
				/* pathing to downstairs on another level */
				level_tile[s->second] = level_tile[level_queue[pivot]];
				level_tile[s->second].updatePath(level_tile[s->second].direction(), level_tile[s->second].distance() + tile.distance() + 1, level_tile[s->second].cost() + tile.cost() + 1);
			}
		}
		/* path to portals on level */
		for (map<Point, int>::const_iterator s = _levels[level_queue[pivot]].symbols((unsigned char) MAGIC_PORTAL).begin(); s != _levels[level_queue[pivot]].symbols((unsigned char) MAGIC_PORTAL).end(); ++s) {
			if (s->second == UNKNOWN_SYMBOL_VALUE)
				continue; // we don't know where this portal leads
			else if (level_added[s->second])
				continue; // already added this level
			Tile& tile = _levels[level_queue[pivot]].tile(s->first);
			if (tile.cost() >= UNPASSABLE)
				continue;
			Debug::info() << "Following magic portal on " << tile.coordinate() << " (" << _levels[level_queue[pivot]].name() << ") leading to level " << s->second << " (" << _levels[s->second].name() << ")" << endl;
			/* we know where this portal leads, add the level to the queue */
			level_added[s->second] = true;
			level_queue[level_count++] = s->second;
			if (pivot == 0) {
				/* pathing to portal on level we're standing on */
				level_tile[s->second] = tile;
				if (tile.direction() == NOWHERE)
					level_tile[s->second].direction(DOWN);
			} else {
				/* pathing to portal on another level */
				level_tile[s->second] = level_tile[level_queue[pivot]];
				level_tile[s->second].updatePath(level_tile[s->second].direction(), level_tile[s->second].distance() + tile.distance() + 1, level_tile[s->second].cost() + tile.cost() + 1);
			}
		}
	}
	return Tile(); // symbol not found
}
示例#29
0
/*
 * Das ist die Standart Bresenham-Algorithmus.
 * Die Lage der Punkte wird nicht geprüft, sondern davon ausgegangen, dass dies schon passiert ist.
 * Die Angabe des Orthanden und der Basis dient der Translation der Koordinaten.
 */
void PrimitiveLine::DrawLineBresenham(ImageBase *img, const Coordinate &to,const char orthant, const Coordinate &offset) const {
	int deltaX = to.GetX();
	int deltaY = to.GetY();
	int e= 2*deltaY - deltaX;
	int x = 0;
	int y = 0;
	Coordinate coord;
	while( x <= deltaX ){
		/* Ruecktransformation der Koordinaten */
		coord = DrawLineTranslateCoordinates(offset,x,y,orthant);

		/* Pixel zeichnen (wenn Koordinaten im Bild) */
		if(coord.GetX() >= 0 && (unsigned)coord.GetX() < img->GetWidth() 
			&& coord.GetY() >= 0 && (unsigned)coord.GetY() < img->GetHeight()) {
			img->SetPixel(coord.GetX(),coord.GetY(),0,GetColor().GetR());
			img->SetPixel(coord.GetX(),coord.GetY(),1,GetColor().GetG());
			img->SetPixel(coord.GetX(),coord.GetY(),2,GetColor().GetB());
		}

		/* Gemaess Bresenham-Algorithmus bestimmen, ob das Pixel rechts vom 
		 * vorigen Pixel oder rechtsoben vom vorigen Pixel gesetzt werden muss */
		if( e > 0 ){
			y++;
			e += 2*(deltaY - deltaX);
		}else{
			e += 2*deltaY;
		}
		x++;
	}
}
示例#30
0
/* public static */
int
Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1)
{
    if (p1.x == p0.x && p1.y == p0.y)
    {
        throw util::IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0.toString());
    }

    if (p1.x >= p0.x) {
        if (p1.y >= p0.y)
            return NE;
        else
            return SE;
    }
    else {
        if (p1.y >= p0.y)
            return NW;
        else
            return SW;
    }
}