01 /**
02 根据给定的三个点绘制抛物线
03 注:是开口向上或向下的抛物线
04 */
05
06 #include <cv.h>
07 #include <highgui.h>
08 #include <iostream>
09 #include <vector>
10 #include <math.h>
11
12 using namespace std;
13 using namespace cv;
14
15 /**
16 给定三个点画抛物线
17 @param image 绘制抛物线的图像
18 @param pL 点1,左边点
19 @param pM 点2,中间点
20 @param pR 点3,右边点
21 @param color 线条颜色
22 */
23 void parabola(Mat &image, Point pL, Point pM, Point pR, const Scalar &color = Scalar(0, 0, 255), int thickness = 1);
24
25 int main(int argc, char *argv[])
26 {
27 const string winName = "test";
28 Mat image = Mat::zeros(480, 640, CV_8UC3);
29 Point pL(200, 200);
30 Point pM(300, 150);
31 Point pR(400, 200);
32 parabola(image, pL, pM, pR);
33
34 namedWindow(winName, 1);
35 imshow(winName, image);
36 waitKey(0);
37 return 1;
38 }
39
40 void parabola(Mat &image, Point pL, Point pM, Point pR, const Scalar &color, int thickness)
41 {
42 /*
43 *抛物线函数y=ax^2+bx+c
44 *已知三个点的横纵坐标为:(x_1, y_1),(x_2, y_2), (x_3, y_3)
45 *关于a,b,c的三元方程组
46 * ax_1^2+bx_1+c=y_1
47 * ax_2^2+bx_2+c=y_2
48 * ax_3^2+bx_3+c=y_3
49 *可得:
50 * a=[(y_1-y_2)/(x_1-x_2)-(y_1-y_3)/(x_1-x_3)]/(x_2-x_3)
51 * b=(y_1-y_2)/(x_1-x_2)-a(x_1+x_2)
52 * c=y_1-ax_1^2-bx_1
53 */
54 double x1, y1, x2, y2, x3, y3, a, b, c;
55 x1 = (double)pL.x;
56 y1 = (double)pL.y;
57 x2 = (double)pM.x;
58 y2 = (double)pM.y;
59 x3 = (double)pR.x;
60 y3 = (double)pR.y;
61 a = ((y1-y2)/(x1-x2)-(y1-y3)/(x1-x3)) / (x2-x3);
62 b = (y1-y2)/(x1-x2)-a*(x1+x2);
63 c = y1-a*x1*x1-b*x1;
64 //x的变化范围是[x1, x3],三像素画一个点
65 int x;
66 double y;
67 vector<Point> pt;
68 for (x = int(x1); x <= int(x3); x = x+3)
69 {
70 y = a * double(x) * double(x) + b * double(x) + c;
71 pt.push_back(Point(x, int(y)));
72 }
73 pt.push_back(Point(int(x3), int(y3)));
74 for (int i = 0; i < pt.size()-1; i++)
75 {
76 line(image, pt[i], pt[i+1], color);
77 }
78 //此处标注出给定的三个点
79 circle(image, Point(pL), 3, color, -1);
80 circle(image, Point(pM), 3, color, -1);
81 circle(image, Point(pR), 3, color, -1);
82 }
绘制结果如下: