You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C++ OpenCV实现从鼠标指定点绘制圆切线的开发需求

实现OpenCV中基于鼠标点绘制圆的切线(C++)

核心流程

要完成从鼠标点击点向半径为4的圆绘制切线的功能,分两步实现:

  • 通过OpenCV鼠标回调获取屏幕鼠标坐标
  • 基于几何计算求出切线切点,再绘制切线

1. 鼠标坐标获取

把你已有的坐标提取逻辑整合到标准OpenCV鼠标回调函数中:

#include <opencv2/opencv.hpp>
using namespace cv;

// 全局变量:存储圆心、鼠标点、是否触发绘制
Point2f circle_center(300, 300); // 示例圆心,可按需调整
Point2f mouse_point;
bool has_mouse_click = false;

void mouseCallback(int event, int x, int y, int flags, void* userdata) {
    if (event == EVENT_LBUTTONDOWN) {
        mouse_point.x = x;
        mouse_point.y = y;
        has_mouse_click = true;
    }
}

2. 切线计算与绘制函数

根据几何推导,实现计算切点并绘制切线的函数:

void drawTangents(Mat& img, const Point2f& center, float radius, const Point2f& outer_point) {
    float dx = outer_point.x - center.x;
    float dy = outer_point.y - center.y;
    float dist_sq = dx*dx + dy*dy;
    float radius_sq = radius*radius;

    // 点在圆内/圆上时无切线
    if (dist_sq <= radius_sq + 1e-6) {
        return;
    }

    float dist = sqrt(dist_sq);
    float cos_theta = sqrt(dist_sq - radius_sq) / dist;
    float sin_theta = radius / dist;

    // 计算两个切点坐标
    Point2f t1, t2;
    t1.x = center.x + dx*cos_theta - dy*sin_theta;
    t1.y = center.y + dy*cos_theta + dx*sin_theta;

    t2.x = center.x + dx*cos_theta + dy*sin_theta;
    t2.y = center.y + dy*cos_theta - dx*sin_theta;

    // 绘制切线与切点
    line(img, outer_point, t1, Scalar(0, 255, 0), 2); // 绿色切线1
    line(img, outer_point, t2, Scalar(0, 255, 0), 2); // 绿色切线2
    circle(img, t1, 2, Scalar(0, 0, 255), -1); // 红色切点1
    circle(img, t2, 2, Scalar(0, 0, 255), -1); // 红色切点2
}

3. 主函数整合

将各部分整合,实现实时交互效果:

int main() {
    Mat img = Mat::zeros(600, 600, CV_8UC3);
    namedWindow("Tangent Demo");
    setMouseCallback("Tangent Demo", mouseCallback);

    while (true) {
        Mat frame = img.clone();
        // 绘制半径为4的目标圆
        circle(frame, circle_center, 4, Scalar(255, 0, 0), -1);

        if (has_mouse_click) {
            drawTangents(frame, circle_center, 4, mouse_point);
        }

        imshow("Tangent Demo", frame);
        if (waitKey(1) == 27) { // 按ESC退出
            break;
        }
    }
    destroyAllWindows();
    return 0;
}

补充说明

  • 示例中圆的圆心固定为(300,300),可根据需求修改circle_center的坐标
  • 点击鼠标左键后,程序自动计算并绘制从点击点到圆的两条切线
  • 代码加入浮点误差容忍值(1e-6),避免精度问题导致的逻辑错误

内容的提问来源于stack exchange,提问作者m baku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:20:38