vector<Coord2D> ParamDistortion::ComputeLocal2DCoord(const vector<Coord>& tri_vtx_coord) { assert(tri_vtx_coord.size() == 3); vector<Coord2D> local_coord(3); local_coord[0] = Coord2D(0, 0); Coord vec_1 = Coord(tri_vtx_coord[1] - tri_vtx_coord[0]); Coord vec_2 = Coord(tri_vtx_coord[2] - tri_vtx_coord[0]); double edge_len_1 = vec_1.abs(); double edge_len_2 = vec_2.abs(); double agl = angle(vec_1, vec_2); local_coord[1] = Coord2D(edge_len_1, 0); double x_3 = edge_len_2*cos(agl); double y_3 = edge_len_2*sin(agl); local_coord[2] = Coord2D(x_3, y_3); return local_coord; }
// ATTENTION : y doit être dans l'intervalle [0;height[ pour que cela fonctionne // ATTENTION : il n'y a pas de contrainte particulière sur le domaine de valeur de x void ScanLineComputer::AddPoint(const int x, const int y, const Coord2D p1, const Coord2D p2, const int index1, const int index2) { // y est la ligne // si le point est plus à gauche que celui que l'on connait pour la ligne y if (x <= left.data[y]) { left.data[y] = x; // on remplace la limite gauche leftweight.data[y].data[0] = 0; // on fixe initialement les poids à 0 leftweight.data[y].data[1] = 0; // on fixe initialement les poids à 0 leftweight.data[y].data[2] = 0; // on fixe initialement les poids à 0 // On calcule les poids associés à ce nouveau point de manière à ce que (x,y)=w1*p1+w2*p2 leftweight.data[y].data[index1] = 1 - p1.Distance(Coord2D(x, y)) / p1.Distance(p2); leftweight.data[y].data[index2] = 1 - leftweight.data[y].data[index1]; } // si le point est plus à droite que celui que l'on connait pour la ligne y if (x >= right.data[y]) { right.data[y] = x; // on remplace la limite droite rightweight.data[y].data[0] = 0; // on fixe initialement les poids à 0 rightweight.data[y].data[1] = 0; // on fixe initialement les poids à 0 rightweight.data[y].data[2] = 0; // on fixe initialement les poids à 0 // On calcule les poids associés à ce nouveau point de manière à ce que (x,y)=w1*p1+w2*p2 rightweight.data[y].data[index1] = 1 - p1.Distance(Coord2D(x, y)) / p1.Distance(p2); rightweight.data[y].data[index2] = 1 - rightweight.data[y].data[index1]; } // on met a jours les limites haut/bas if (y < ymin) ymin = y; if (y > ymax) ymax = y; }
Coord2D Coord2D::neighbor(Direction dir) const { //方向向量 struct Vec2D { Coord1D x; Coord1D y; }; //方向的向量单位值 const Vec2D dirVecUnit[] = { {0, 0}, {-1, -1}, {0, -1}, {+1, -1}, {-1, 0}, {+1, 0}, {-1, +1}, {0, +1}, {+1, +1}, }; Vec2D vec = dirVecUnit[static_cast<uint32_t>(dir)]; return Coord2D(x + vec.x, y + vec.y); }
bool Drawing::DrawingImpl::getCoordFromMouseClick(int x, int y, Coord2D &coord) { // the user clicked near or directly into the waypoint int left = std::max(0, x - ROBOT_DIAMETER / 2); int right = std::min(static_cast<int>(texture->width()) - 1, x + ROBOT_DIAMETER / 2); int bottom = std::max(0, y - ROBOT_DIAMETER / 2); int top = std::min(static_cast<int>(texture->height()) - 1, y + ROBOT_DIAMETER / 2); for (int i = bottom; i <= top; i++) { for (int j = left; j <= right; j++) { coord = Coord2D(j, i); if (room->hasWaypoint(coord)) { return true; } } } return false; }
Coord2D Coord2D::middle(const Coord2D& other) const { return Coord2D((x + other.x) / 2, (y + other.y) / 2); }
Coord2D Coord2D::operator*(const float &n) const { return Coord2D(u*n, v*n); }
Coord2D Coord2D::operator+(const Coord2D &c) const { return Coord2D(u + c.u, v + c.v); }
Triangle::Triangle(const Vertex &va, const Normal &na, const Vertex &vb, const Normal &nb, const Vertex &vc, const Normal &nc) { points[0] = va, points[1] = vb, points[2] = vc; norms[0] = na, norms[1] = nb, norms[2] = nc; tcoords[0] = Coord2D(), tcoords[1] = Coord2D(), tcoords[2] = Coord2D(); }
Triangle::Triangle(const Vertex &va, const Vertex &vb, const Vertex &vc) { points[0] = va, points[1] = vb, points[2] = vc; norms[0] = Normal(), norms[1] = Normal(), norms[2] = Normal(); tcoords[0] = Coord2D(), tcoords[1] = Coord2D(), tcoords[2] = Coord2D(); }
void Drawing::DrawingImpl::mouseClick(int x, int y) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, texture->width(), 0, texture->height(), -1.0f, 4.0f); throwErrorFromGLError(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Texture glTranslatef(0.0f, 0.0f, -3.5f); GLdouble modelview[16], projection[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetDoublev(GL_PROJECTION_MATRIX, projection); GLfloat z; glReadPixels(x, viewport[3] - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); GLdouble posX, posY, posZ; gluUnProject(x, y, z, modelview, projection, viewport, &posX, &posY, &posZ); throwErrorFromGLError(); x = posX; y = posY; bool changed = false; switch (waypointModification) { case Drawing::WaypointAdd: changed = room->insertWaypoint(Coord2D(x, y)); break; case Drawing::WaypointDelete: changed = delNode(x, y); break; case Drawing::WaypointStart: changed = room->setStartpoint(Coord2D(x, y)); break; case Drawing::WaypointEnd: changed = room->setEndpoint(Coord2D(x, y)); break; default: if (show_[ShowNeighbours]) { Coord2D coord; if (!getCoordFromMouseClick(x, y, coord)) { return; } showNeighbours(coord); } break; } if (changed) { updateRoom(); } }
/******************************** * DrawLine : Fonction qui réalise le rendu filaire selon l'algorithme de Bresenham *******************************/ void Buffer::DrawLine(const Coord2D p1, const Coord2D p2, const Color c1, const Color c2) { int y = p1.y, x = p1.x; int longX = p2.x - p1.x, longY = p2.y - p1.y; int const2 = 0, const1 = 0, critere = 0; Color c = c1; double depth; double wa = 0.0, wb = 0.0; int incX = 0, incY = 0; int compteur = 0; if(longX >= 0){ incX++; } else{ incX--; longX *= (-1); } if(longY >= 0){ incY++; } else{ incY--; longY *= (-1); } if(longY < longX){ const1 = 2 * (longY - longX); const2 = 2*longY; critere = const2 - longX; for(compteur=1; compteur <= longX; compteur++){ wa = 1 - (sqrt((p1.x - x)*(p1.x - x)+(p1.y - y)*(p1.y - y)))/(sqrt((p1.x - p2.x)*(p1.x - p2.x)+(p1.y - p2.y)*(p1.y - p2.y))); wb = 1- wa; c.red = (1/(wa+ wb)) * (wa*c1.red + wb*c2.red); c.blue = (1/(wa+ wb)) * (wa*c1.blue + wb*c2.blue); c.green = (1/(wa+ wb)) * (wa*c1.green + wb*c2.green); depth = (1/(wa+ wb)) * (wa*p1.depth + wb*p2.depth); SetPoint(Coord2D(x, y, depth), c); if(critere > 0){ y = y + incY; critere = critere + const1; } else{ critere = critere + const2; } x = x +incX; } } else{ const1 = 2 * (longX - longY); const2 = 2*longX; critere = const2 - longY; for(compteur=1; compteur <= longY; compteur++){ wa = 1 - (sqrt((p1.x - x)*(p1.x - x)+(p1.y - y)*(p1.y - y)))/(sqrt((p1.x - p2.x)*(p1.x - p2.x)+(p1.y - p2.y)*(p1.y - p2.y))); wb = 1- wa; c.red = (1/(wa+ wb)) * (wa*c1.red + wb*c2.red); c.blue = (1/(wa+ wb)) * (wa*c1.blue + wb*c2.blue); c.green = (1/(wa+ wb)) * (wa*c1.green + wb*c2.green); depth = (1/(wa+ wb)) * (wa*p1.depth + wb*p2.depth); SetPoint(Coord2D(x, y, depth), c); if(critere > 0){ x = x + incX; critere = critere + const1; } else{ critere = critere + const2; } y = y +incY; } } }