精华内容
下载资源
问答
  • C# 判断两条直线距离

    千次阅读 热门讨论 2018-06-29 16:28:18
    本文告诉大家获得两条一般式直线距离

    本文告诉大家获得两条一般式直线距离



    一般式的意思就是

    Ax+By+C=0 A x + B y + C = 0

    如果有两个直线

    A1x+B1y+C1=0A2x+B2y+C2=0 A 1 x + B 1 y + C 1 = 0 A 2 x + B 2 y + C 2 = 0

    如何判断两条直线的距离?

    如果需要判断两条直线的距离,首先两条直线需要是平行

    判断一般式直线平行的方法

    A1B2A2B10 A 1 B 2 − A 2 B 1 ≈ 0

    如果两条直线符合上面公式,可以认为两条直线平行。

    对于一般的两条直线,获得距离的公式

    d=|C1C2|A2+B2 d = | C 1 − C 2 | A 2 + B 2

    但是因为两个直线一般式的 AB 是不相等的,所以需要把两个直线转换相同的 AB

    A1x+B1y+C1=0A2xA1A2+B2yA1A2+C2A1A2=0A1x+B1y+C2A1A2=0 A 1 x + B 1 y + C 1 = 0 A 2 x A 1 A 2 + B 2 y A 1 A 2 + C 2 A 1 A 2 = 0 A 1 x + B 1 y + C 2 A 1 A 2 = 0

    这时的距离公式是

    d=C1C2A1A2A21+B21 d = | C 1 − C 2 A 1 A 2 | A 1 2 + B 1 2

    但是存在 A 或 B 是 0 ,所以就不能直接使用上面的距离

    如果 a=0,b0 a = 0 , b ≠ 0 那么需要修改直线公式

    B1y+C1=0B1y+C2B1B2=0 B 1 y + C 1 = 0 B 1 y + C 2 B 1 B 2 = 0

    这时距离公式

    d=C1C2B1B2B1 d = | C 1 − C 2 B 1 B 2 | B 1

    如果 a0,b=0 a ≠ 0 , b = 0 那么需要修改直线公式

    A1x+C1=0A1x+C2A1A2=0 A 1 x + C 1 = 0 A 1 x + C 2 A 1 A 2 = 0

    这时距离公式

    d=C1C2A1A2A1 d = | C 1 − C 2 A 1 A 2 | A 1

    因为我是在编程,我可以拿到距离平方,这样可以减少开方,我把上面的公式写为代码,代码是C#不过大家可以把他使用其他语言

           /// <summary>
            /// 获得两条直线的距离,传入的直线已经是判断平行
            /// </summary>
            /// <param name="otherLine"></param>
            /// <returns></returns>
            public double? GetDistanceWithLineSquare(LineEquation otherLine)
            {
                var aIsZero = A.IsZero();
                var bIsZero = B.IsZero();
    
                //D=|C1-C2|/sqrt(A^2+B^2)
    
                // A 是 0 ,但是 B 不是 0
                if (aIsZero && !bIsZero)
                {
                    //B1Y+C1=0 B1Y+B1/B2*C2=0
                    return Math.Abs(C - B / otherLine.B * otherLine.C) / B*B;
                }
    
                if (!aIsZero && bIsZero)
                {
                    //A1X+C1=0 A1X+A1/A2*C2=0
                    return Math.Abs(C - A / otherLine.A * otherLine.C) / A*A;
                }
    
                if (!aIsZero && !bIsZero)
                {
                    return Math.Abs(C - A / otherLine.A * otherLine.C) / (A * A + B * B);
                }
    
                if (aIsZero && bIsZero)
                {
                    return default(double?);
                }
                return default(double?);
            }

    我搭建了自己的博客 https://lindexi.gitee.io/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

    如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

    展开全文
  • OpenCV计算两条平行线之间距离

    千次阅读 2019-04-23 08:25:48
    //第四部 计算两条直线之间距离 公式是: |b1-b0| / sqrt(A*A + B*B) float dis = abs(b[1]-b[0])/sqrt(A*A + B*B); printf("dis is %f \n" , dis); // 释放内存 cvReleaseImage(&pSrc); ...

    代码来自www.opencvchina.com

    #include "cv.h"
    #include "highgui.h"
    #include "cxcore.h"
    #include <stdlib.h>
    #include <stdio.h>
    
    #ifndef LINESDISHEADER
    
    #define LINESDISHEADER
    
    //对输入图像进行细化
    void ThinImage(IplImage* src, IplImage* dst, int iterations=1);
    
    //获取图像上的轮廓 坐标 
    void GetContoursPoints(IplImage* src , CvMat** LinePoints);
    
    #endif
    
    
    
    
    #include "LinesDis.h"
    
    
    //对输入图像进行细化
    void ThinImage(IplImage* src, IplImage* dst, int iterations)
    {
     CvSize size = cvGetSize(src);
    
     cvCopy(src, dst);//拷贝一个数组给另一个数组
        int n = 0,i = 0,j = 0;
     for(n=0; n<iterations; n++)
     {
    IplImage* t_image;
     
     t_image = cvCloneImage(dst);
      for(i=0; i<size.height;  i++)
      {
       for(int j=0; j<size.width; j++)
       {
        if(CV_IMAGE_ELEM(t_image,byte,i,j)==1)
        {
         int ap=0;
         int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);
         int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);
         if (p2==0 && p3==1)
         {
          ap++;
         }
         int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);
         if(p3==0 && p4==1)
         {
          ap++;
         }
         int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);
         if(p4==0 && p5==1)
         {
          ap++;
         }
         int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);
         if(p5==0 && p6==1)
         {
          ap++;
         }
         int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);
         if(p6==0 && p7==1)
         {
          ap++;
         }
         int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);
         if(p7==0 && p8==1)
         {
          ap++;
         }
         int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);
         if(p8==0 && p9==1)
         {
          ap++;
         }
         if(p9==0 && p2==1)
         {
          ap++;
         }
         if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7)
         {
          if(ap==1)
          {
           if(p2*p4*p8==0)
           {
            if(p2*p6*p8==0)
            {
             CV_IMAGE_ELEM(dst, byte,i,j)=0;
            }
           }
          }
         }                    
        }
    
       }
    
      }            
      cvReleaseImage(&t_image);
    
    }
    
     //将二值图像转换成灰度,以便显示
      i = 0;j = 0;
      size = cvGetSize(dst);
     for(i=0; i<size.height;  i++)
     {
      for(j=0; j<size.width; j++)
      {
       if(CV_IMAGE_ELEM(dst,uchar,i,j)==1)
       {
        CV_IMAGE_ELEM(dst,uchar,i,j) = 255;
       }
       else
       {
        CV_IMAGE_ELEM(dst,uchar,i,j) = 0;
       }
      }
     }
    
    }
    
    //获取图像上的轮廓 坐标 
    void GetContoursPoints(IplImage* src , CvMat** LinePoints)
    {
    	CvMemStorage* storage = cvCreateMemStorage(0);
    	CvSeq* contour = 0;
    	IplImage* binary_image = cvCreateImage(cvGetSize(src),8,1);
    	cvCopy(src,binary_image);
    
    	cvFindContours(binary_image , storage , &contour , sizeof(CvContour) , CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE,cvPoint(0,0) );
    
    //#define SHOWCON
    #ifdef SHOWCON
    	IplImage* contours;
    	contours = cvCreateImage(cvGetSize(src),8,1);
    	cvZero(contours);
    	cvNamedWindow("con");
    #endif 
    
    	int LinesCount = 0;
    
    	for(;contour!=0 ; contour=contour->h_next)
    	{
    		if(contour->total < 20 )continue;
    
    		LinePoints[LinesCount] = cvCreateMat(contour->total/8,1,CV_32FC2);
    		
    	
    		for(int i=0; i<contour->total/8 ; i++)
    		{
    	
    			CvPoint * pt = (CvPoint*)cvGetSeqElem(contour, i); // 读出第i个点。
    			cvSet2D(LinePoints[LinesCount] , i,0,cvScalar(pt->x,src->height - pt->y,0,0));
    
    			//cvSetReal2D(contours , pt->y , pt->x , 255.0);
    #ifdef SHOWCON
    			CvScalar val = cvGet2D(LinePoints[LinesCount] , i, 0);
    			cvSetReal2D(contours , val.val[1] ,val.val[0],255);
    		
    			cvShowImage("con" ,contours);
    			cvWaitKey(0);
    #endif
    
    		
    		}
    		LinesCount++;
    
    	}
    
    #ifdef SHOWCON
    	for(int i=0;i<LinesCount;i++)
    	{
    		for(int y=0;y<LinePoints[i]->rows;y++)
    		{
    			CvScalar pt = cvGet2D(LinePoints[i] , y, 0);
    			cvSetReal2D(contours , pt.val[1] ,pt.val[0],255);
    			printf("(%f,%f) ",pt.val[0],pt.val[1]);
    		}
    	}
    
    
    	cvShowImage("con" ,contours);
    	cvWaitKey(0);
    #endif
    
    	cvReleaseMemStorage(&storage);
    	cvReleaseImage(&binary_image);
    
    }

     

    // ComputeLinesDis.cpp : Defines the entry point for the console application.
    //
    
    
    
    #include "LinesDis.h"
    
    int main(int argc, char* argv[])
    {
    	//对两条直线进行细化
    	IplImage *pSrc = NULL,*pDst = NULL,*pTmp = NULL;
    
    	//传入一个灰度图像,从文件中读取图像
    	pSrc = cvLoadImage("1.png",CV_LOAD_IMAGE_GRAYSCALE);
    	if(!pSrc)
    	{
    		return 0;
    	}
    
    	pTmp = cvCreateImage(cvGetSize(pSrc),pSrc->depth , pSrc->nChannels);
        pDst = cvCreateImage(cvGetSize(pSrc),pSrc->depth,pSrc->nChannels);
    	cvZero(pDst);//初始化
    	cvThreshold(pSrc,pTmp,128,1,CV_THRESH_BINARY_INV);//做二值处理,将图像转换成0,1
     
    	//第一步 对图像中的直线进行细化
    	ThinImage(pTmp,pDst,80);
    
    
    #define SHOWRESULT
    #ifdef SHOWRESULT
    	cvNamedWindow("src",1);//创建窗口
    	cvNamedWindow("dst",1);
    	cvShowImage("src",pSrc);
    	cvShowImage("dst",pDst);
    #endif
    
    
    
    
    
    	//第二步  提取直线的轮廓坐标
    	CvMat*LinesPoints[2];
    	LinesPoints[0]=0;LinesPoints[1]=0;
    	GetContoursPoints(pDst,LinesPoints);
    
    //#define SHOWCONT
    #ifdef SHOWCONT
    	IplImage* contours = cvCreateImage(cvGetSize(pDst),8,1);
    	cvZero(contours);
    	cvNamedWindow("Mcon");
    	for(int i=0;i<2;i++)
    	{
    		for(int y=0;y<LinesPoints[i]->rows;y++)
    		{
    			CvScalar pt = cvGet2D(LinesPoints[i] , y, 0);
    			cvSetReal2D(contours , pt.val[1] ,pt.val[0],255);
    			cvShowImage("Mcon" ,contours);
    		}
    	}
    
    
    	cvWaitKey(0);
    #endif
    
    
    	//第三步 对轮廓上的坐标进行直线拟合 计算直线方程 By = Ax + b
    	float params[4] , k[2] , b[2] , A , B;
    	cvFitLine(LinesPoints[0] , CV_DIST_L2,1,0.001,0.001,params);
    	k[0] = params[1]/params[0];
    	b[0] = params[3] - k[0]*params[2];
    	A    = k[0];
    	B    = 1;
    
    	printf("y=%f*x+%f \n",k[0]*180.0/3.1415,b[0]);
    
    	cvFitLine(LinesPoints[1] , CV_DIST_L2,1,0.001,0.001,params);
    	k[1] = params[1]/params[0];
    	b[1] = params[3] - k[0]*params[2];
    
    	printf("y=%f*x+%f \n",k[1]*180.0/3.1415,b[1]);
    
    	//第四部  计算两条直线之间的距离 公式是: |b1-b0| / sqrt(A*A + B*B)
    	float 	dis = abs(b[1]-b[0])/sqrt(A*A + B*B);
    
    	printf("dis is %f \n" , dis); 
    
    
    
    	// 释放内存
        cvReleaseImage(&pSrc);
    	cvReleaseImage(&pDst);
    	cvReleaseImage(&pTmp);
    
    	if(LinesPoints[0])
    	cvReleaseMat(&LinesPoints[0]);
    	
    	if(LinesPoints[1]);
    	cvReleaseMat(&LinesPoints[1]);
    	cvWaitKey(0);
    
    	return 0;
    }
    
    

     

     

     

    展开全文
  • 平行线之间距离

    2015-07-02 21:49:23
    计算图片中两条平行线之间距离,代码完整,非常使用,不可错过额
  • 【opencv】两条平行线之间距离

    万次阅读 2014-03-10 23:05:42
    问题:一张输入图片如下,有两条平行线两条平行线之间距离 解决思路: 1. 对图像中的直线进行细化 2. 提取直线的轮廓坐标 3. 对轮廓上的坐标进行直线集合,从而得到直线方程 4. 计算两条直线之间距离 ...

    问题:一张输入图片,图片上有两条平行线,求出这两条平行线之间的距离

    解决思路:

    1. 对图像中的直线进行细化

    2. 提取直线的轮廓坐标

    3. 对轮廓上的坐标进行直线集合,从而得到直线方程

    4. 计算两条直线之间的距离

    参考:

    问题来源 http://www.opencvchina.com/thread-854-1-1.html

    图像细化 http://blog.csdn.net/qianchenglenger/article/details/19332011

    图像轮廓提取 http://blog.csdn.net/augusdi/article/details/9000893

    直线拟合 http://blog.csdn.net/zhuoyue08/article/details/6803040

    两条直线之间的距离公式3:http://zhidao.baidu.com/link?url=ef_DHNkjyq1qq7VgubX3afL2KIUQIB4ukd3zHGp0zz8iPPKC046azyvG5ltHR-i0WaLI72eO7j0sOJI4wZSE4q

    工具:

     opencv 2.4.8 + VS2013

    代码:

    1.头文件 ProcessImage.h

    //ProcessImage.h
    #pragma once
    #include <opencv2/highgui/highgui.hpp>
    
    /* 对输入图像进行细化
     * src为输入图像,用cvThreshold函数处理过的8位灰度图像格式,元素中只有0与1,1代表有元素,0代表为空白
     * dst为对src细化后的输出图像,格式与src格式相同,调用前需要分配空间,元素中只有0与1,1代表有元素,0代表为空白
     * maxIterations限制迭代次数,如果不进行限制,默认为-1,代表不限制迭代次数,直到获得最终结果
     */
    void thinImage(IplImage* src, IplImage* dst, int maxIterations = -1);
    

    2.代码实现 ProcessImage.cpp

    //ProcessImage.cpp
    #include "ProcessImage.h"
    #include <utility>
    #include <vector>
    void thinImage(IplImage* src, IplImage* dst, int maxIterations)
    {
    	using namespace cv;
    	CvSize size = cvGetSize(src);
    	cvCopy(src, dst);//将src中的内容拷贝到dst中  
    	int count = 0;  //记录迭代次数  
    	while (true)
    	{
    		count++;
    		if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达  
    			break;
    		//std::cout << count << ' ';输出迭代次数  
    		std::vector<std::pair<int, int> > mFlag; //用于标记需要删除的点  
    		//对点标记  
    		for (int i = 0; i<size.height; ++i)
    		{
    			for (int j = 0; j<size.width; ++j)
    			{
    				//如果满足四个条件,进行标记  
    				//  p9 p2 p3  
    				//  p8 p1 p4  
    				//  p7 p6 p5  
    				int p1 = CV_IMAGE_ELEM(dst, uchar, i, j);
    				int p2 = (i == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j);
    				int p3 = (i == 0 || j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j + 1);
    				int p4 = (j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i, j + 1);
    				int p5 = (i == size.height - 1 || j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j + 1);
    				int p6 = (i == size.height - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j);
    				int p7 = (i == size.height - 1 || j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j - 1);
    				int p8 = (j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i, j - 1);
    				int p9 = (i == 0 || j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j - 1);
    
    				if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
    				{
    					int ap = 0;
    					if (p2 == 0 && p3 == 1) ++ap;
    					if (p3 == 0 && p4 == 1) ++ap;
    					if (p4 == 0 && p5 == 1) ++ap;
    					if (p5 == 0 && p6 == 1) ++ap;
    					if (p6 == 0 && p7 == 1) ++ap;
    					if (p7 == 0 && p8 == 1) ++ap;
    					if (p8 == 0 && p9 == 1) ++ap;
    					if (p9 == 0 && p2 == 1) ++ap;
    
    					if (ap == 1)
    					{
    						if (p2*p4*p6 == 0)
    						{
    							if (p4*p6*p8 == 0)
    							{
    								//标记  
    								mFlag.push_back(std::make_pair(i, j));
    							}
    						}
    					}
    				}
    			}
    		}
    
    		//将标记的点删除  
    		for (std::vector<std::pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i)
    		{
    			CV_IMAGE_ELEM(dst, uchar, i->first, i->second) = 0;
    		}
    
    		//直到没有点满足,算法结束  
    		if (mFlag.size() == 0)
    		{
    			break;
    		}
    		else
    		{
    			mFlag.clear();//将mFlag清空  
    		}
    
    		//对点标记  
    		for (int i = 0; i<size.height; ++i)
    		{
    			for (int j = 0; j<size.width; ++j)
    			{
    				//如果满足四个条件,进行标记  
    				//  p9 p2 p3  
    				//  p8 p1 p4  
    				//  p7 p6 p5  
    				int p1 = CV_IMAGE_ELEM(dst, uchar, i, j);
    				if (p1 != 1) continue;
    				int p2 = (i == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j);
    				int p3 = (i == 0 || j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j + 1);
    				int p4 = (j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i, j + 1);
    				int p5 = (i == size.height - 1 || j == size.width - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j + 1);
    				int p6 = (i == size.height - 1) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j);
    				int p7 = (i == size.height - 1 || j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i + 1, j - 1);
    				int p8 = (j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i, j - 1);
    				int p9 = (i == 0 || j == 0) ? 0 : CV_IMAGE_ELEM(dst, uchar, i - 1, j - 1);
    
    				if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6)
    				{
    					int ap = 0;
    					if (p2 == 0 && p3 == 1) ++ap;
    					if (p3 == 0 && p4 == 1) ++ap;
    					if (p4 == 0 && p5 == 1) ++ap;
    					if (p5 == 0 && p6 == 1) ++ap;
    					if (p6 == 0 && p7 == 1) ++ap;
    					if (p7 == 0 && p8 == 1) ++ap;
    					if (p8 == 0 && p9 == 1) ++ap;
    					if (p9 == 0 && p2 == 1) ++ap;
    
    					if (ap == 1)
    					{
    						if (p2*p4*p8 == 0)
    						{
    							if (p2*p6*p8 == 0)
    							{
    								//标记  
    								mFlag.push_back(std::make_pair(i, j));
    							}
    						}
    					}
    				}
    			}
    		}
    		//删除  
    		for (std::vector<std::pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i)
    		{
    			CV_IMAGE_ELEM(dst, uchar, i->first, i->second) = 0;
    		}
    
    		//直到没有点满足,算法结束  
    		if (mFlag.size() == 0)
    		{
    			break;
    		}
    		else
    		{
    			mFlag.clear();//将mFlag清空  
    		}
    	}
    }
    
    3.主函数所在文件 Source.cpp

    //Source.cpp
    #include "ProcessImage.h"
    #include <iostream>
    #include <opencv2/opencv.hpp>
    #define _TEST
    using namespace cv;
    int main(int argc, char * argv[])
    {
    	//判断输入是否满足要求
    	if (argc != 2)
    	{
    		std::cout << "argument error!";
    		return -1;
    	}
    	IplImage *pSrc = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    	if (!pSrc)
    	{
    		std::cout << "read file failed!";
    		return -1;
    	}
    
    	//显示原图
    	namedWindow("原图", CV_WINDOW_AUTOSIZE);
    	cvShowImage("原图", pSrc);
    
    	IplImage *pTemp = cvCreateImage(cvGetSize(pSrc), pSrc->depth, pSrc->nChannels);
    	IplImage *pDst = cvCreateImage(cvGetSize(pSrc), pSrc->depth, pSrc->nChannels);
    
    	//将原图像转换为二值图像
    	cvThreshold(pSrc, pTemp, 128, 1, CV_THRESH_BINARY_INV);
    	//细化
    	thinImage(pTemp, pDst);
    
    #ifdef _TEST
    	//显示细化后的图像
    	IplImage *pThinImage = cvCreateImage(cvGetSize(pSrc), pSrc->depth, pSrc->nChannels);
    	cvCopy(pDst, pThinImage);
    	cvThreshold(pThinImage, pThinImage, 0.5, 255,CV_THRESH_BINARY);
    	namedWindow("1 图像细化的结果", CV_WINDOW_AUTOSIZE);
    	cvShowImage("1 图像细化的结果", pThinImage);
    	cvReleaseImage(&pThinImage);
    #endif
    
    	//求轮廓
    	CvMemStorage* storage = cvCreateMemStorage(0);
    	CvSeq* contours = 0;
    	cvFindContours(pDst	, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
    
    #ifdef _TEST
    	//将轮廓画出来
    	IplImage *pDrawing1 = cvCreateImage(cvGetSize(pSrc),8,3);
    	cvZero(pDrawing1);
    	cvDrawContours(pDrawing1, contours, Scalar(255, 0, 0), Scalar(0, 0, 255), 1, 2, 8, cvPoint(0, 0));
    	namedWindow("2 求轮廓", CV_WINDOW_AUTOSIZE);
    	cvShowImage("2 求轮廓", pDrawing1);
    	cvReleaseImage(&pDrawing1);
    #endif
    
    
    	//轮廓已经寻找到,均在contours中存放,我们需要对轮廓进行拟合
    	//FitLine函数的用法:
    	// 二维空间点拟合时 是 float[4]
    	// 三位空间点拟合时 是 float[6]	
    	float *line1 = new float[4];
    	float *line2 = new float[4];
    	// 第一个参数: 存储点序列
    	// 第二个参数: 拟合算法,其中 CV_DIST_L2 就是平常的最小二乘法
    	// 第三,第四,第五参数推荐值是 0,   0.01,  0.01,
    	// 第六参数: line中存储返回值
    	// 二维空间时: line[0--3] 分别为 (vx, vy, x0, y0)
    	//      其中 vx, vy 是正规化之后的斜率向量。 x0,y0 是直线经过的点。
    	// 三维空间时: line[0--5]  分别是 (vx, vy, vz, x0, y0, z0) 。意义同上
    	cvFitLine(contours, CV_DIST_L2, 0, 0.01, 0.01, line1);
    	cvFitLine(contours->h_next, CV_DIST_L2, 0, 0.01, 0.01, line2);
    	
    	//输出四个点
    	std::cout << "第一条线: " << line1[0] << " " << line1[1] << " " << line1[2] << " " << line1[3] << std::endl;
    	std::cout << "第二条线: " << line2[0] << " " << line2[1] << " " << line2[2] << " " << line2[3] << std::endl;
    	
    #ifdef _TEST
    	//根据直线方程公式,我们从直线上取点,并画出来
    	IplImage *pDrawing2 = cvCreateImage(cvGetSize(pSrc), 8, 3);
    	cvZero(pDrawing2);
    	cvLine(pDrawing2, cvPoint(0, (int)(line1[3] - line1[1] / line1[0] * line1[2])),
    		cvPoint(pDrawing2->width - 1, (int)((pDrawing2->width - 1 - line1[2])*line1[1] / line1[0] + line1[3])),
    		cvScalar(255, 0, 0));
    	cvLine(pDrawing2, cvPoint(0, (int)(line2[3] - line2[1] / line2[0] * line2[2])), 
    		cvPoint(pDrawing2->width - 1, (int)((pDrawing2->width - 1 - line2[2])*line2[1] / line2[0] + line2[3])), 
    		cvScalar(0, 0, 255));
    	namedWindow("3 直线拟合", CV_WINDOW_AUTOSIZE);
    	cvShowImage("3 直线拟合", pDrawing2);
    	cvReleaseImage(&pDrawing2);
    #endif
    
    	//我们根据距离方程,求出两条直线的距离
    	double distance = abs(line1[0] * (line2[3]-line1[3]) - line1[1] * (line2[2]-line1[2]));	//注意,vx,vy已经正规化了
    	std::cout << "两条直线之间的距离为: " << distance << std::endl;
    	delete[] line1;
    	delete[] line2;
    
    	cvReleaseMemStorage(&storage);
    	cvReleaseImage(&pSrc);
    	cvReleaseImage(&pTemp);
    	cvReleaseImage(&pDst);
    
    	waitKey(0);
    
    	return 0;
    }
    运行效果:

    输入:

    输出:


    展开全文
  • 也可以理解为 :三角形一个... /// 计算两条直线的交点 /// </summary> /// <param name="lineFirstStar">L1的点1坐标</param> /// <param name="lineFirstEnd">L1的点2坐标</param&g...

    也可以理解为 :三角形一个顶点 连接 内部某一个点,延长后和另一条边的交点。 

     

     

     

      /// <summary>
            /// 计算两条直线的交点
            /// </summary>
            /// <param name="lineFirstStar">L1的点1坐标</param>
            /// <param name="lineFirstEnd">L1的点2坐标</param>
            /// <param name="lineSecondStar">L2的点1坐标</param>
            /// <param name="lineSecondEnd">L2的点2坐标</param>
            /// <returns></returns>
            public static XYZ GetIntersection(XYZ lineFirstStar, XYZ lineFirstEnd, XYZ lineSecondStar, XYZ lineSecondEnd)
            {
               
                XYZ rexyz = new XYZ(0,0,0);
                double a = 0, b = 0;
                int state = 0;
                if (lineFirstStar.X != lineFirstEnd.X)
                {
                    a = (lineFirstEnd.Y - lineFirstStar.Y) / (lineFirstEnd.X - lineFirstStar.X);
                    state |= 1;
                }
                if (lineSecondStar.X != lineSecondEnd.X)
                {
                    b = (lineSecondEnd.Y - lineSecondStar.Y) / (lineSecondEnd.X - lineSecondStar.X);
                    state |= 2;
                }
                switch (state)
                {
                    case 0: //L1与L2都平行Y轴
                        {
                            if (lineFirstStar.X == lineSecondStar.X)
                            {
                                //throw new Exception("两条直线互相重合,且平行于Y轴,无法计算交点。");
                                return new XYZ(0, 0, 0);
                            }
                            else
                            {
                                //throw new Exception("两条直线互相平行,且平行于Y轴,无法计算交点。");
                                return new XYZ(0, 0, 0);
                            }
                        }
                    case 1: //L1存在斜率, L2平行Y轴
                        {
                            double x = lineSecondStar.X;
                            double y = (lineFirstStar.X - x) * (-a) + lineFirstStar.Y;
                            return new XYZ(x, y,0);
                        }
                    case 2: //L1 平行Y轴,L2存在斜率
                        {
                            double x = lineFirstStar.X;
                            //网上有相似代码的,这一处是错误的。你可以对比case 1 的逻辑 进行分析
                            //源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
                            double y = (lineSecondStar.X - x) * (-b) + lineSecondStar.Y;
                            return new XYZ(x, y,0);
                        }
                    case 3: //L1,L2都存在斜率
                        {
                            if (a == b)
                            {
                                // throw new Exception("两条直线平行或重合,无法计算交点。");
                                return new XYZ(0, 0,0);
                            }
                            double x = (a * lineFirstStar.X - b * lineSecondStar.X - lineFirstStar.Y + lineSecondStar.Y) / (a - b);
                            double y = a * x - a * lineFirstStar.X + lineFirstStar.Y;
                            return new XYZ(x, y,0);
                        }
                }
                // throw new Exception("不可能发生的情况");
                return new XYZ(0, 0,0);
            }
    
    

     

    展开全文
  • // 得到直线的tan斜率 double GetTanOfLine( LINE line ) { double x_dis = line.pt0.x - line.pt1.x; if ( x_dis == 0.0 ) return 10e9; return (line.pt0.y - line.pt1.y) / x_...// 得到两条平行线之间距离 dou
  • 下面是修正后的/// /// 计算两条直线的交点/// /// L1的点1坐标/// L1的点2坐标/// L2的点1坐标/// L2的点2坐标/// public static PointF GetIntersection(PointF lineFirstStar, PointF lineFirstEnd, PointF ...
  • 这个函数只考虑了二维空间的交。 GetInterBetweenTwoLines函数即为交点函数。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ...
  • //连接终点与起点的边 } //处理平行线 叉乘判断平行,计算并判断平行两线距离若是,保存线的坐标 double crossProduct( int ptA_x, float ptA_y, float ptB_x, float ptB_y) { double cp = ptA_x * ptB_y - ptB_...
  • c#平行线和垂线的代码

    千次阅读 2017-02-05 15:14:41
    参考如下绘制平行线的代码 private Point downPoint = Point.Empty; // 鼠标按下的坐标 private Point movePoint = Point.Empty; // 鼠标移动的坐标 private double lineSpace = 12.0f; // 线条之间距离 private ...
  • title author date CreateTime categories ... C# 判断两条直线距离 lindexi 2018-07-31 14:38:13 +0800 2018-05-08 10:32:50 +0800 数学 C# 几何 本文告诉大家获得两条一般式直线距离。 ...
  • bool dayu(Point p1, Point p2)////比较点坐标大小,先比较x坐标,若相同则比较y坐标 { return (p1.X > p2.X || (Equal(p1.X , p2.X) && p1.Y > p2.Y)); } bool dengyu(Point p1, Point p2)//
  • 1 引言 问题:已知三维空间中四点A、B、C、D,如何判断线段AB与CD是否相交,若相交则出交点。 分析: AB、CD要相交,则AB、CD必须要在同一平面内 ...很简单,个向量的叉乘就是这个向量所在平面的法线。
  • C# 计算两条线段交点的位置

    千次阅读 2017-05-03 11:53:42
    AB本身就是两条直线,知道两端点就可以知道其直线方程,B也是一样,两个方程联立, 得到一个坐标,再看该坐标是否在B的定义域内就可以啊 首先,我们指定直线方程都有: 1:一般式:Ax+By+C=0(A、B不同时为0)...
  • 1: /// <summary> 2: /// 判断两条线是否相交 3: /// </summary> 4: /// <param name="a">线段1起点坐标</param> 5: /// <param name="b">...
  • Unity3d异面直线求距离

    2018-07-24 17:36:22
    //求直线和平面的交点 public static Vector3 intersectLineAndPlane(Vector3 _linePt, Vector3 _lineDir, Vector3 _plnNormal, Vector3 _plnPt) { float d = Vector3.Dot(_plnPt - _linePt, _plnNormal) / ...
  • ctx.arcTo() 可以绘制与两条直线相切的圆弧; 2. function draw() { var canvas = document.getElementById('canv'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx....
  • 题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,...
  • /// 点到线段最短距离的那条直线与线段的交点,{x=...,y=...} /// /// 线段外的点的x坐标 /// 线段外的点的y坐标 /// 线段顶点1的x坐标 /// 线段顶点1的y坐标 /// 线段顶点2的x坐标 /// 线段顶点2的y坐标 ...
  • /// 判断两条线是否相交 /// </summary> /// <param name="a">线段1起点坐标</param> /// <param name="b">线段1终点坐标</param> /// <param name="c">线段2起点...
  • 判断两线段是否平行

    2019-10-01 23:13:18
    //判断两条线段是否相交的测试代码 //对于垂直的线段暂时没有作考虑,如果需要后续加上判断即可,应该不难 //author:challenKing //data:2010-07-06 class test { public static void main(String[] args) { ...
  • 2)平面中的两条直线的相对位置有三种情况,相交、平行、重合; 假设有两条直线,他的方程为a1x+b1y=c1;a2x+b2y=c2,判断两条直线的位置关系的代码如下: //----------------- //a1x+b1y=c1 //a2x+b2y=c2 //----...
  • 首先,假设有两条线段p,q,两条线段的空间关系。 我们把两条线段的四个顶点看为向量,用坐标表示:p1(p1x,p1y), p2(p2x,p2y), q1(q1x,q1y), q2(q2x, q2y) 则可以计算出两线段对应向量: p = p2 - p1 q =...
  • 判断两条直线的夹角

    千次阅读 2018-05-17 16:23:17
     /// 判断要素是否平行 /// &lt;/summary&gt; /// &lt;returns&gt;&lt;/returns&gt; protected bool GeometryParallel(IFeature pFeat,out Lineside pSide) { ...
  • revit二次开发 两条线是否平行两条线是否垂直
  • 一般方程法: 直线的一般方程为F(x) = ax + by + c = 0。既然我们已经知道直线的两个点,假设为(x0,y0), (x1, y1),...因此我们可以将两条直线分别表示为 F0(x) = a0*x + b0*y + c0 = 0, F1(x) = a1*x + b1*y +
  • 两条直线的夹角

    千次阅读 2020-02-29 15:17:38
    编写一个c++程序,计算四个点所构成的两条直线的夹角 setprecision(n)描述:可以控制输出流显示浮点数的数字个数。...注意:当两直线平行或者重合,答案为0。 测试举例: 测试输入:0 0 1 0 0 0 0...
  • 如何在一曲线上,获取到距离指定点最近的点位置? 与上一篇 C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值 类似, 我们通过曲线上获取的密集点,通过俩点之间连线,获取连线上最近的点。我们能够获取到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,516
精华内容 606
关键字:

c#求两条平行直线之间的距离

c# 订阅