bool pointInTriangleTest(double* pointP, double* pointA, double* pointB, double* pointC) { // get the barycentric coordinate double AB[3], AC[3], PB[3], PC[3], PA[3]; double areaABC = triangleArea(pointA, pointB, pointC); double areaABP = triangleArea(pointA, pointB, pointP); double areaACP = triangleArea(pointA, pointC, pointP); double alpha = areaABP / areaABC; double beta = areaACP / areaABC; double gamma = 1 - alpha - beta; return (alpha >=0 && beta >=0 && gamma >= 0); }
int main(int, char**){ MyImage image; //Set up parameters for the triangl vec2 v0(100, 100); vec2 v1(200, 300); vec2 v2(400, 50); float TotalArea = triangleArea(v0, v1, v2); //rasterize the triangle for (int row = 0; row < image.rows; ++row) { for (int col = 0; col < image.cols; ++col) { vec2 pt(col, row); /// Calculate the barycentric coordinates using the triangle area } } image.show(); // image.save("output.png"); ///< Does not work on Windows! return EXIT_SUCCESS; }
bool isPointInTriangle1(TPoint p, TTriangle t) { //判断点是否在三角形内,面积判断 TTriangle tmp; double area; int i, j; area = 0; for(i = 0;i <= 2;i++){ for(j = 0;j <= 2;j++){ if(i == j) tmp.t[j] = p; else tmp.t[j] = t.t[j]; } area += triangleArea(tmp); } return same(area, triangleArea(t)); }
TCircle circumcircleOfTriangle(TTriangle t) { //三角形的外接圆 TCircle tmp; double a, b, c, c1, c2; double xA, yA, xB, yB, xC, yC; a = distance(t.t[0], t.t[1]); b = distance(t.t[1], t.t[2]); c = distance(t.t[2], t.t[0]); //根据S = a * b * c / R / 4;求半径R tmp.r = a * b * c / triangleArea(t) / 4; xA = t.t[0].x; yA = t.t[0].y; xB = t.t[1].x; yB = t.t[1].y; xC = t.t[2].x; yC = t.t[2].y; c1 = (xA * xA + yA * yA - xB * xB - yB * yB) / 2; c2 = (xA * xA + yA * yA - xC * xC - yC * yC) / 2; tmp.centre.x = (c1 * (yA - yC) - c2 * (yA - yB)) / (xA - xB) * (yA - yC) - (xA - xC) * (yA - yB); tmp.centre.y = (c1 * (xA - xC) - c2 * (xA - xB)) / (yA - yB) * (xA - xC) - (yA - yC) * (xA - xB); return tmp; }
/// Get the area for a face float EmitterMesh::faceArea(const MeshFace& face) const { float area = 0; for(int i = 3; i <= face.numVerts; ++i) area += triangleArea(&face.v[0] + i-3); return area; }
TEST_F(TerrainBlockTest, data) { Point2D<int> southWestPixel(position.x() * 256, (position.y() + 1) * 256); Point2D<int> northEastPixel((position.x() + 1) * 256, position.y() * 256); Point2D<double> southWest = GeoPoint::fromPixel(southWestPixel, zoomLevel, 256).toWebMercator(); Point2D<double> northEast = GeoPoint::fromPixel(northEastPixel, zoomLevel, 256).toWebMercator(); double referenceArea = (float(northEast.x()) - float(southWest.x())) * (float(northEast.y()) - float(southWest.y())); const std::vector<float>& vertexBuffer = terrainBlock->vertexBuffer(); const auto& indexBuffer = TerrainBlock::indexBuffer(); ASSERT_EQ(75, vertexBuffer.size()); ASSERT_EQ(96, indexBuffer.size()); auto readPolygon = [&](int startPosition) -> std::tuple<Point3D<float>, Point3D<float>, Point3D<float>> { return std::make_tuple(Point3D<float>(vertexBuffer[indexBuffer[startPosition] * 3], vertexBuffer[indexBuffer[startPosition] * 3 + 1], vertexBuffer[indexBuffer[startPosition] * 3 + 2]), Point3D<float>(vertexBuffer[indexBuffer[startPosition + 1] * 3], vertexBuffer[indexBuffer[startPosition + 1] * 3 + 1], vertexBuffer[indexBuffer[startPosition + 1] * 3 + 2]), Point3D<float>(vertexBuffer[indexBuffer[startPosition + 2] * 3], vertexBuffer[indexBuffer[startPosition + 2] * 3 + 1], vertexBuffer[indexBuffer[startPosition + 2] * 3 + 2])); }; double terrainBlockArea = 0; std::unordered_set<long> heights; for (int i = 0; i < indexBuffer.size(); i += 3) { auto polygon = readPolygon(i); const Point3D<float>& p1 = std::get<0>(polygon); const Point3D<float>& p2 = std::get<1>(polygon); const Point3D<float>& p3 = std::get<2>(polygon); EXPECT_FALSE(p1 == p2); EXPECT_FALSE(p1 == p3); EXPECT_FALSE(p2 == p3); terrainBlockArea += triangleArea(p1, p2, p3); long h1 = lround(p1.z()); long h2 = lround(p2.z()); long h3 = lround(p3.z()); EXPECT_NE(0, h1); EXPECT_NE(0, h2); EXPECT_NE(0, h3); heights.insert(h1); heights.insert(h2); heights.insert(h3); } EXPECT_FLOAT_EQ(referenceArea, terrainBlockArea); EXPECT_EQ(62 - 55 + 1, heights.size()); }
// Ray Plane Collision - returns true if collsion exists bool Collision::RayPlane(const float& normalX, const float& normalY, const float& normalZ, float pointOnPlaneX, float pointOnPlaneY, float pointOnPlaneZ, float initialX, float initialY, float initialZ, float directionX, float directionY, float directionZ, Vector3d p1, Vector3d p2, Vector3d p3, Vector3d p4, float* distance, Vector3d* collisionPoint){ // if the dot product == 0 then there is no collision if((directionX * normalX + directionY * normalY + directionZ * normalZ) == 0){ return false; } float t = ((pointOnPlaneX * normalX + pointOnPlaneY * normalY + pointOnPlaneZ * normalZ - normalX * initialX - normalY * initialY - normalZ * initialZ) / (directionX * normalX + directionY * normalY + directionZ * normalZ)); // if t is a negative.....or (in this case) < 0 the intersection point // is in the opposite direction... this indicates there is no collision // i like to think as t representing scalar time here....since time is directed // along a negative axis (which cant be)...it would denote no collision and evaluate to false. if(t < 0){ return false; } // intialize a point that is used for testing the collision of the ray and a triangle of the plane. float x = initialX + t * directionX; float y = initialY + t * directionY; float z = initialZ + t * directionZ; Vector3d rayPoint(x, y, z); float precision = 0.3; // test to see if the sum of the three sub triangles equals the triangle from which they // are derived...precision is used here in case the subtraction of the triangles are off by say like .0000000001 // exgerated i know, but used to illustrate the point. p1, p2, p3, and p4 are the vertices of the plane. // the first test in the if statement is for the first triangle after the quad was subdivided // simularly the second test in the if statement is for the other triangle. if(std::abs(triangleArea(p1, p2, p3) - (triangleArea(p1, p2, rayPoint) + triangleArea(p2, p3, rayPoint) + triangleArea(p1, p3, rayPoint))) < precision || std::abs(triangleArea(p1, p3, p4) - (triangleArea(p1, p3, rayPoint) + triangleArea(p3, p4, rayPoint) + triangleArea(p1, p4, rayPoint))) < precision){ if(distance != NULL){ (*distance) = t; if(collisionPoint != NULL){ collisionPoint->setX(x); collisionPoint->setY(y); collisionPoint->setZ(z); } } return true; } return false; }
int main() { //freopen("in.in", "r", stdin); //freopen("OUT.out", "w", stdout); TPoint p1, p2, p3; while(scanf("%d%d%d%d%d%d", &p1.x, &p1.y, &p2.x, &p2.y, &p3.x, &p3.y) != EOF){ if(p1.x == 0 && p1.y == 0 && p2.x == 0 && p2.y == 0 && p3.x == 0 && p3.y == 0) break; int A = triangleArea(p1, p2, p3);//A为面积的两倍 int b = 0; int i; b = Count(p1, p2) + Count(p1, p3) + Count(p3, p2) - 3;//3个顶点多各多加了一次 //i = A / 2- b / 2 + 1; i = (A - b) / 2 + 1; printf("%d\n", i); } return 0; }
TCircle incircleOfTriangle(TTriangle t) { //三角形的内接圆 TCircle tmp; double a, b, c, angleA, angleB, angleC, p, p2, p3, f1, f2; double xA, yA, xB, yB, xC, yC; a = distance(t.t[0], t.t[1]); b = distance(t.t[1], t.t[2]); c = distance(t.t[2], t.t[0]); /* S = p * r p = (a + b + c) / 2; r = S / P = 2 * S / (a + b + c) */ tmp.r = 2 * triangleArea(t) / (a + b +c); angleA = acos((b * b + c * c - a * a) / (2 * b * c)); angleB = acos((a * a + c * c - b * b) / (2 * a * c)); angleC = acos((a * a + b * b - c * c) / (2 * a * b)); p = sin(angleA / 2); p2 = sin(angleB / 2); p3 = sin(angleC / 2); xA = t.t[0].x; yA = t.t[0].y; xB = t.t[1].x; yB = t.t[1].y; xC = t.t[2].x; yC = t.t[2].y; f1 = ((tmp.r / p2) * (tmp.r / p2) - (tmp.r / p) * (tmp.r / p) + xA * xA - xB * xB + yA * yA - yB * yB) / 2; f2 = ((tmp.r / p3) * (tmp.r / p3) - (tmp.r / p) * (tmp.r / p) + xA * xA - xC * xC + yA * yA - yC * yC) / 2; tmp.centre.x = (f1 * (yA - yC) - f2 * (yA - yB)) / ((xA - xB) * (yA - yC) - (xA - xC) * (yA - yB)); tmp.centre.y = (f1 * (xA - xC) - f2 * (xA - xB)) / ((yA - yB) * (xA - xC) - (yA - yC) * (xA - xB)); return tmp; }
std::vector<Vector2> NavMesh::FindStraightPath(const Vertices& vertices, const std::vector<NavTriangle *> &path) { std::vector<Vector2> straightPath; if (path.empty()) { return straightPath; } std::vector<Vector2> portalsLeft; std::vector<Vector2> portalsRight; portalsLeft.push_back(path[path.size()-1]->position); portalsRight.push_back(path[path.size()-1]->position); for (int i=(int)path.size()-1; i>=1; i--) { NavTriangle* current = path[i]; NavTriangle* next = path[i-1]; int forwardIndex = current->FindNeighborIndex(next); portalsRight.push_back(vertices[current->corners[forwardIndex]]); portalsLeft.push_back(forwardIndex<2 ? vertices[current->corners[forwardIndex + 1]] : vertices[current->corners[0]]); } portalsLeft.push_back(path[0]->position); portalsRight.push_back(path[0]->position); Vector2 portalApex = portalsLeft[0]; Vector2 portalLeft = portalsLeft[0]; Vector2 portalRight = portalsRight[0]; int apexIndex = 0, leftIndex = 0, rightIndex = 0; straightPath.push_back(portalApex); for (int i=1; i<portalsLeft.size(); i++) { Vector2 left = portalsLeft[i]; Vector2 right = portalsRight[i]; // Update right vertex. if (triangleArea(portalApex, portalRight, right) <= 0.0f) { if (portalApex.EqualEpsilon(portalRight) || triangleArea(portalApex, portalLeft, right) > 0.0f) { // Tighten the funnel. portalRight = right; rightIndex = i; } else { // Right over left, insert left to path and restart scan from portal left point. straightPath.push_back(portalLeft); // Make current left the new apex. portalApex = portalLeft; apexIndex = leftIndex; // Reset portal portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; // Restart scan i = apexIndex; continue; } } // Update left vertex. if (triangleArea(portalApex, portalLeft, left) >= 0.0f) { if (portalApex.EqualEpsilon(portalLeft) || triangleArea(portalApex, portalRight, left) < 0.0f) { portalLeft = left; // Tighten the funnel. leftIndex = i; } else { // Left over right, insert right to path and restart scan from portal right point. straightPath.push_back(portalRight); // Make current right the new apex. portalApex = portalRight; apexIndex = rightIndex; // Reset portal portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; // Restart scan i = apexIndex; continue; } } } straightPath.push_back(path[0]->position); /* const float radius = 1.0f; std::vector<Vector2> offsetedPath; offsetedPath.push_back(straightPath[0]); for (int i=1; i<straightPath.size()-1; i++) { Vector2 forward = straightPath[i] - straightPath[i-1]; Vector2 backwards = straightPath[i] - straightPath[i+1]; forward.Normalize(); backwards.Normalize(); Vector2 normal = forward + backwards; normal.Normalize(); offsetedPath.push_back(straightPath[i]+normal * radius); } offsetedPath.push_back(straightPath[straightPath.size() - 1]); */ return straightPath; }
int main() { { miyabi::type_traits::dump< Foo >( std::cout ); std::cout << std::endl; miyabi::type_traits::dump< miyabi::ContainerFacade< Foo > >( std::cout ); std::cout << std::endl; miyabi::type_traits::dump< boost::array< float, 4 > >( std::cout ); } { miyabi::math::Vector< std::vector< float > > a( 3 ); a[ 0 ] = 3; a[ 1 ] = 4; a[ 2 ] = 5; miyabi::math::Vector< std::vector< float > > b( 4 ); b[ 0 ] = 0; b[ 1 ] = 3; b[ 2 ] = 6; b[ 3 ] = 9; miyabi::math::Vector< std::map< int, float > > c; c[ 0 ] = 1; c[ 3 ] = 2; c[ 7 ] = 3; c[ 9 ] = 4; miyabi::math::Vector< std::map< int, float > > d; d[ 0 ] = 1; d[ 2 ] = 4; d[ 3 ] = 8; d[ 5 ] = 12; miyabi::math::Vector< std::map< int, float > > result3 = c + d; std::cout << result3 << std::endl; c += d; std::cout << c[ 0 ] << " " << c[ 1 ] << " " << c[ 2 ] << " " << c[ 3 ] << " "; std::cout << c[ 4 ] << " " << c[ 5 ] << " " << c[ 6 ] << " " << c[ 7 ] << " "; std::cout << c[ 8 ] << " " << c[ 9 ] << " " << c[ 10 ] << " " << c[ 11 ] << std::endl; c += a; std::cout << c[ 0 ] << " " << c[ 1 ] << " " << c[ 2 ] << " " << c[ 3 ] << " "; std::cout << c[ 4 ] << " " << c[ 5 ] << " " << c[ 6 ] << " " << c[ 7 ] << " "; std::cout << c[ 8 ] << " " << c[ 9 ] << " " << c[ 10 ] << " " << c[ 11 ] << std::endl; miyabi::math::Vector< std::map< int, float > > da; da[ 0 ] = 1; miyabi::math::Vector< std::map< int, float > > db; db[ 2 ] = 1; std::cout << dot( da, da ) << std::endl; std::cout << dot( da, db ) << std::endl; miyabi::math::Vector< std::vector< float > > result = a + b; std::cout << &result.getBase() << std::endl; std::cout << result.size() << " " << result[ 1 ] << " " << result[ 2 ] << " " << result[ 3 ] << std::endl; miyabi::math::Vector< std::vector< float > > result2 = b - a; std::cout << result2[ 0 ] << " " << result2[ 1 ] << " " << result2[ 2 ] << " " << result2[ 3 ] << std::endl; miyabi::math::Vector< std::map< int, miyabi::math::Vector< std::map< int, float > > > > matrix; matrix[ 5 ][ 2 ] = 1; std::cout << matrix << std::endl; miyabi::math::outer_return_vector< miyabi::math::Vector< std::vector< float > >, miyabi::math::Vector< std::vector< float > > >::type ext_result = a * b; std::cout << ext_result << std::endl; miyabi::math::Vector< std::map< int, float > > foo; foo[ 90 ] = 1; foo[ 2048 ] = 1; std::cout << length( foo ) << std::endl; } { miyabi::math::Vector< std::map< int, float > > v1;v1[ 1 ]=1; miyabi::math::Vector< std::map< int, float > > v2;v2[ 0 ]=1; miyabi::math::Vector< std::map< int, float > > v3; std::cout << triangleArea( v1, v2, v3 ) << std::endl; miyabi::math::Vector< std::map< int, miyabi::math::Vector< std::map< int, float > > > > matrix2; for( int row = 0; row != 10; ++row ) for( int col = 0; col != 10; ++col ) matrix2.getValue( rand() % 16 ).getValue( rand() % 16 ) = rand() % 256; miyabi::math::Vector< std::vector< float > > log; for( int row = 0; row != 16; ++row ) log.getValue( row ) = row; std::cout << log << std::endl; std::cout << matrix2 << std::endl; lu( matrix2, log ); std::cout << matrix2 << std::endl; std::cout << log << std::endl; } { miyabi::math::Vector< std::map< int, miyabi::math::Vector< std::map< int, float > > > > mx; mx[0][0]=1;mx[0][1]=4;mx[0][2]=3;mx[0][3]=8; mx[1][1]=2;mx[1][2]=5;mx[1][3]=1; mx[2][0]=9;mx[2][1]=3; mx[3][0]=5; mx[3][2]=1;mx[3][3]=1; std::cout << inverse( mx ) << std::endl; std::cout << mx << std::endl; } { miyabi::math::Vector< std::vector< float > > v1( 3 ); v1[ 0 ] = 1.0f; v1[ 1 ] = 0.0f; v1[ 2 ] = 0.0f; miyabi::math::Vector< std::vector< float > > v2( 3 ); v2[ 0 ] = 0.0f; v2[ 1 ] = 1.0f; v2[ 2 ] = 0.0f; miyabi::math::Vector< std::vector< float > > v3 = cross( v1, v2 ); std::cout << v3 << std::endl; } { miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > polygon( 3 ); polygon.getValue( 0 ).getValue( 0 ) = 1.0f; polygon.getValue( 0 ).getValue( 1 ) = 0.0f; polygon.getValue( 0 ).getValue( 2 ) = 0.0f; polygon.getValue( 1 ).getValue( 0 ) = 0.0f; polygon.getValue( 1 ).getValue( 1 ) = 0.0f; polygon.getValue( 1 ).getValue( 2 ) = 1.0f; polygon.getValue( 2 ).getValue( 0 ) = 0.0f; polygon.getValue( 2 ).getValue( 1 ) = 1.0f; polygon.getValue( 2 ).getValue( 2 ) = 0.0f; typename miyabi::radiosity::triangle_matrix_return_vector< miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > >::type result = miyabi::radiosity::getTriangleMatrix( polygon ); polygon.getValue( 0 ).getValue( 3 ) = 1.0f; polygon.getValue( 1 ).getValue( 3 ) = 1.0f; polygon.getValue( 2 ).getValue( 3 ) = 1.0f; std::cout << result << std::endl; std::cout << result * polygon[ 0 ] << std::endl; std::cout << result * polygon[ 1 ] << std::endl; std::cout << result * polygon[ 2 ] << std::endl; // std::cout << triangleArea( v1, v2, v3 ) << " " << triangleArea( result * v1, result * v2, result * v3 ) << std::endl; } { miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > m; m.getValue( 0 ).getValue( 0 ) = -1; m.getValue( 0 ).getValue( 1 ) = 0; m.getValue( 0 ).getValue( 2 ) = 1; m.getValue( 1 ).getValue( 0 ) = 0; m.getValue( 1 ).getValue( 1 ) = -0.5f; m.getValue( 1 ).getValue( 2 ) = 1; m.getValue( 2 ).getValue( 0 ) = 0.0f; m.getValue( 2 ).getValue( 1 ) = 0.0f; m.getValue( 2 ).getValue( 2 ) = 1; inverse( m ); miyabi::math::Vector< std::vector< float > > v; v.getValue( 0 ) = 0; v.getValue( 1 ) = 0; v.getValue( 2 ) = 5; miyabi::math::Vector< std::vector< float > > r = m * v; std::cout << r << std::endl; r[ 0 ]; std::cout << -r[ 0 ] + r[ 2 ] << std::endl; std::cout << -0.5 * r[ 1 ] + r[ 2 ] << std::endl; std::cout << 0.2 * r[ 0 ] + 0.5 * r[ 1 ] + r[ 2 ] << std::endl; } { miyabi::math::Vector< std::vector< float > > p1; p1.getValue( 0 ) = 0; p1.getValue( 1 ) = 0; p1.getValue( 2 ) = 0; miyabi::math::Vector< std::vector< float > > p2; p2.getValue( 0 ) = 1; p2.getValue( 1 ) = 1; p2.getValue( 2 ) = 1; miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > m; m.getValue( 0 ).getValue( 0 ) = 10; m.getValue( 0 ).getValue( 1 ) = 0; m.getValue( 0 ).getValue( 2 ) = 0; m.getValue( 1 ).getValue( 0 ) = 0; m.getValue( 1 ).getValue( 1 ) = 10; m.getValue( 1 ).getValue( 2 ) = 0; m.getValue( 2 ).getValue( 0 ) = 0; m.getValue( 2 ).getValue( 1 ) = 0; m.getValue( 2 ).getValue( 2 ) = 10; std::cout << "i1 " << miyabi::radiosity::intersect( p1, p2, m ) << std::endl; std::cout << "i2 " << miyabi::radiosity::intersect2( p1, p2, m ) << std::endl; } { miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > p; p.getValue( 0 ).getValue( 0 ) = 5; p.getValue( 0 ).getValue( 1 ) = 1; p.getValue( 0 ).getValue( 2 ) = -10; p.getValue( 1 ).getValue( 0 ) = 5; p.getValue( 1 ).getValue( 1 ) = 2; p.getValue( 1 ).getValue( 2 ) = -3; p.getValue( 2 ).getValue( 0 ) = 5; p.getValue( 2 ).getValue( 1 ) = 3; p.getValue( 2 ).getValue( 2 ) = 8; miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > m; m.getValue( 0 ).getValue( 0 ) = 10; m.getValue( 0 ).getValue( 1 ) = 0; m.getValue( 0 ).getValue( 2 ) = 0; m.getValue( 1 ).getValue( 0 ) = 0; m.getValue( 1 ).getValue( 1 ) = 10; m.getValue( 1 ).getValue( 2 ) = 0; m.getValue( 2 ).getValue( 0 ) = 0; m.getValue( 2 ).getValue( 1 ) = 0; m.getValue( 2 ).getValue( 2 ) = 10; std::cout << miyabi::radiosity::cut( p, m ) << std::endl; } { miyabi::math::Vector< std::vector< miyabi::math::Vector< std::vector< float > > > > p; p.getValue( 0 ).getValue( 0 ) = 0; p.getValue( 0 ).getValue( 1 ) = 0; p.getValue( 0 ).getValue( 2 ) = 0; p.getValue( 1 ).getValue( 0 ) = 1; p.getValue( 1 ).getValue( 1 ) = 0; p.getValue( 1 ).getValue( 2 ) = 0; p.getValue( 2 ).getValue( 0 ) = 1; p.getValue( 2 ).getValue( 1 ) = 1; p.getValue( 2 ).getValue( 2 ) = 0; p.getValue( 3 ).getValue( 0 ) = 0; p.getValue( 3 ).getValue( 1 ) = 1; p.getValue( 3 ).getValue( 2 ) = 0; std::cout << area( p ) << std::endl; } }