三角形光栅化算法

版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/zhouyelihua https://blog.csdn.net/zhouyelihua/article/details/78822980

原理解释:http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html

//
// Created by yyy on 12/6/17.
//
#include <iostream>
using namespace std;
#include<fstream>
#include<opencv2/opencv.hpp>
#include<opencv2/core.hpp>
#include<opencv/cv.h>
#include<vector>
void drawLine(cv::Mat& mat,int x1,int y1,int x2,int y2){
    for(int i=x1;i<=x2;i++){
           mat.at<int>(y1,i)=1;
    }

}
void fillBottomFlatTriangle(cv::Mat& mat,cv::Point& v1,cv::Point& v2,cv::Point& v3){
    float invslope1 = float(v2.x - v1.x) / float(v2.y - v1.y);
    float invslope2 = float(v3.x - v1.x) / float(v3.y - v1.y);

    float curx1 = v1.x;
    float curx2 = v1.x;

    for (int scanlineY = v1.y; scanlineY <= v2.y; scanlineY++)
    {
    drawLine(mat,(int)curx1, scanlineY, (int)curx2, scanlineY);
      curx1 += invslope1;
      curx2 += invslope2;
    }
}

void fillTopFlatTriangle(cv::Mat& mat,cv::Point& v1,cv::Point& v2,cv::Point& v3){

  float invslope1 = float(v3.x - v1.x) / float(v3.y - v1.y);
  float invslope2 = float(v3.x - v2.x) / float(v3.y - v2.y);

  float curx1 = v3.x;
  float curx2 = v3.x;

  for (int scanlineY = v3.y; scanlineY > v1.y; scanlineY--)
  {
  drawLine(mat,(int)curx1, scanlineY, (int)curx2, scanlineY);
    curx1 -= invslope1;
    curx2 -= invslope2;
  }
}

void drawTriangle( cv::Mat& mat,std::vector<cv::Point>& triPts)
{
   /* at first sort the three vertices by y-coordinate ascending so v1 is the topmost vertice */
     std::sort(triPts.begin(),triPts.end(),[](cv::Point& p1,cv::Point&p2){return (p1.y==p2.y)?p1.x<p2.x : p1.y<p2.y;});
       cv::Point& v1=triPts[0];
       cv::Point& v2=triPts[1];
       cv::Point& v3=triPts[2];

  /* here we know that v1.y <= v2.y <= v3.y */
  /* check for trivial case of bottom-flat triangle */
  if (v2.y == v3.y)
  {
    fillBottomFlatTriangle(mat,v1, v2, v3);
  }
  /* check for trivial case of top-flat triangle */
  else if (v1.y == v2.y)
  {
    fillTopFlatTriangle(mat, v1, v2, v3);
  }
  else
  {
    /* general case - split the triangle in a topflat and bottom-flat one */
    cv::Point v4(
      (int)(v1.x + ((float)(v2.y - v1.y) / (float)(v3.y - v1.y)) * (v3.x - v1.x)), v2.y);
    fillBottomFlatTriangle(mat, v1, v2, v4);
    fillTopFlatTriangle(mat, v2, v4, v3);
  }
}

int main()
{

    cv::Mat mm(30,20,CV_32SC1,cv::Scalar(0));
    cv::Mat mmm(30,20,CV_32SC1,cv::Scalar(0));
    std::vector<cv::Point> triPts2(3);
   triPts2[0]=(cv::Point(12,2));
   triPts2[1]=(cv::Point(2,9));
  triPts2[2]=(cv::Point(17,29));
   drawTriangle(mm,triPts2);
   cv::fillConvexPoly(mmm,triPts2,cv::Scalar(1));   //opencv 光栅化
   std::cout<<"\n";   std::cout<<"\n";   std::cout<<"\n";
   for(int i=0;i<mm.rows;i++){
       for(int j=0;j<mm.cols;j++){
            std::cout<<mm.at<int>(i,j)<<" ";
        }
    std::cout<<"\n";
    }
   std::cout<<"\n";   std::cout<<"\n";
   std::cout<<"\n";   std::cout<<"\n";   std::cout<<"\n";
   for(int i=0;i<mmm.rows;i++){
       for(int j=0;j<mmm.cols;j++){
            std::cout<<mmm.at<int>(i,j)<<" ";
        }
    std::cout<<"\n";
    }
   std::cout<<"\n";   std::cout<<"\n";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouyelihua/article/details/78822980
今日推荐