OpenGL+QT二维图形拾取算法

1、拾取直线的算法

        点到直线的距离公式 ,将鼠标的坐标遍历所有直线,得出来的每一个距离是否小于阈值来判断是否选中       

//点到线的距离公式(鼠标X,Y坐标,直线两端点P1,P2坐标,计算结果返回值OutDistent)
bool AXBOpenGLWidget::PointToLind(float x, float y, float P1_x, float P1_y, float P2_x, float P2_y,float* OutDistent)
{
    bool inRange;
    //判断是否竖直
    if(P1_x==P2_x)
    {
        if (((y>P1_y)&&(y<P2_y))||((y>P2_y)&&(y<P1_y)))
           inRange=true;
        else
            inRange=false;

    }//判断是否水平
    else if(P1_y==P2_y)
    {
        if (((x>P1_x)&&(x<P2_x))||((x>P2_x)&&(x<P1_x)))
           inRange=true;
        else
            inRange=false;
    }
    else
    {
        if (((y>P1_y)&&(y<P2_y)&&(x>P2_x)&&(x<P1_x))||((y>P1_y)&&(y<P2_y)&&(x>P1_x)&&(x<P2_x))||((y>P2_y)&&(y<P1_y)&&(x>P1_x)&&(x<P2_x))||((y>P2_y)&&(y<P1_y)&&(x>P2_x)&&(x<P1_x)))
           inRange=true;
        else
            inRange=false;
    }
    if(!inRange)
    {
        *OutDistent =0;
        return inRange;
    }
    float fenmu = sqrt(qPow((P1_y-P2_y),2)+qPow((P1_x-P2_x),2));
    *OutDistent = qAbs((P1_y-P2_y)*x+(P2_x-P1_x)*y+P1_x*P2_y-P2_x*P1_y)/fenmu;
    return inRange;
}

2、拾取圆的算法

        (也可以通过圆环来实现)

        (也可以用两点之间的距离小于半径)

        点在圆内,通过圆心坐标+半径,得到正方形范围。点在正方形范围内即可。

bool AXBOpenGLWidget::pointInCir(float x, float y, float c_x, float c_y, float R)
{
    float P1_y=c_y-R;
    float P1_x=c_x-R;
    float P2_y=c_y+R;
    float P2_x=c_x+R;
    if (((y>P1_y)&&(y<P2_y)&&(x>P1_x)&&(x<P2_x)))
       return true;
    else
        return false;
}

3、拾取圆弧的算法

        1、点在圆弧的角度范围内

                圆弧起始角度<=向量(点与圆心)与X轴的角度<=圆弧的终止角度

        2、点到圆心点的距离小于等于半径

                 点到圆心的距离<=半径

                (也可以通过圆弧环来实现)

        实现过程:

                1、任一点与X轴的夹角是多少?获取向量角度

//点(起始点,终止点,鼠标点,与X轴的角度)(点,圆心坐标)
float GCodeFile::Angle_with_XAxis(float X,float Y,float Ce_x,float Ce_y)
{
         //向量与X轴的夹角
        float b2a[2] = { X-Ce_x , Y -Ce_y },
        Axle[2] = { 1, 0 };

        float dotProduct = 0.0; //向量点乘
        float a1 = 0.0;//向量模长
        float b1 = 0.0;//向量模长
        float cosr = 0.0;//向量夹角

        dotProduct = b2a[0] * Axle[0] + b2a[1] * Axle[1];
        a1 = sqrt(b2a[0] * b2a[0] + b2a[1] * b2a[1]);
        b1 = 1;


        cosr = dotProduct /(a1 * b1);//余弦值
        cosr = acos(cosr) * 180 / 3.1415926;//转换为角度  。acos范围是0~ 180°
        if((Y-Ce_y)<0)
        {
            cosr=360-cosr;             //转化为0到360°
        }
        return cosr;

}

                2、两点之间的距离

                        

float AXBOpenGLWidget::Point2PointDist(float x1, float y1, float x2, float y2)
{
    //两点之间的距离
   return sqrt(qPow((x1-x2),2)+qPow((y1-y2),2));
}

                3、是否在圆弧内

                

bool AXBOpenGLWidget::pointInArc(float x, float y, float c_x, float c_y, float R, float StartAngle, float EndAngle)
{
    //得到鼠标到圆心的向量与X轴的角度
     float CurrentAngle=Angle_with_XAxis(x,y,c_x,c_y);
     //鼠标与圆心的距离
     float Distent=Point2PointDist(x,y,c_x,c_y);
     //距离小半径,角度在起点和终点之间
     if(Distent<=R&&(CurrentAngle>=StartAngle)&&(CurrentAngle<=EndAngle))
     {
         return true;
     }
     return false;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值