[从头学数学] 第201节 几何证明选讲

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第七转的修炼。
这次要研究的是[几何证明选讲]。

正剧开始:

星历2016年05月01日 14:07:58, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[几何证明选讲]。


[从头学数学] 第201节 几何证明选讲_第1张图片

[从头学数学] 第201节 几何证明选讲_第2张图片

[从头学数学] 第201节 几何证明选讲_第3张图片


谈到直线,小伟觉得有必要计算一些东西。


比如平面上两点之间的距离:

<span style="font-size:18px;">#两点之间
#平面两点的距离[x1, y1] -- [x2, y2]
def distance2D(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    return ((x2-x1)**2+(y2-y1)**2)**0.5;</span>


直线的斜率:

<span style="font-size:18px;">#平面直线的斜率[x1, y1] -- [x2, y2]
def slope(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    if (x1 == x2):
        return 'inf';
    else:
        return (y2-y1)/(x2-x1);</span>


直线的截距:

<span style="font-size:18px;">#平面直线的截距[x1, y1] -- [x2, y2]
def interceptOfLine(Point_1, Point_2):
    k = slope(Point_1, Point_2);

    if k == 'inf':
        return [k, Point_1[0], 1e8];
    elif k == 0:
        return [k, 1e8, Point_1[1]];
    else:
        return [k, Point_1[0]-Point_1[1]/k, Point_1[1]-Point_1[0]*k];
    
</span>

从X轴逆时针旋转多少度,才能转成直线的角度呢?

<span style="font-size:18px;">#平面直线与X轴的夹角[x1, y1] -- [x2, y2]
def angleFromX(Point_1, Point_2):
    x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1];

    delta = ((x2-x1)**2+(y2-y1)**2)**0.5;
    dx = x2 - x1;
    dy = y2 - y1;
    
    sin = math.asin(dy / delta)/math.pi*180;
    cos = math.acos(dx / delta)/math.pi*180;

    if (dy >= 0 and dx >= 0):
        return math.asin(dy / delta)/math.pi*180;
    elif (dy >= 0 and dx < 0):
        return 180- math.asin(dy / delta)/math.pi*180;
    elif (dy < 0 and dx <= 0):
        return 180 - math.asin(dy / delta)/math.pi*180;
    else:
        return 360 + math.asin(dy / delta)/math.pi*180;</span>


两条直线是不是平行,要怎样才能知道?

<span style="font-size:18px;">#两直线之间
#两直线是否平行 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def parallelCheck(Line_1, Line_2):
    L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
    k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);
    if  k1 == k2 == 'inf':
        return True;
    elif k1 != 'inf' and k2 != 'inf' and abs(k1 - k2) < 1e-6:
        return True;

    return False;</span>


两条直线的距离呢?

<span style="font-size:18px;">#两直线距离 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def lineDistance2D(Line_1, Line_2):
    if parallelCheck(Line_1, Line_2):
        L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
        k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);

        if k1 == 'inf':
            return abs(L1_Point_1[0] - L2_Point_1[0]);
        else:
            dx = L1_Point_1[0] - L2_Point_1[0];
            dy = k1*dx;
            return abs((L2_Point_1[1]+dy-L1_Point_1[1])/(1+k1**2)**0.5);

    else:
        return 0;
</span>

两条直线的夹角:

<span style="font-size:18px;">#两直线夹角 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def angleBetweenTwoLine(Line_1, Line_2):
    L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];

    return angleFromX(L2_Point_1, L2_Point_2) - angleFromX(L1_Point_1, L1_Point_2);</span>

两条直线的交点:

<span style="font-size:18px;">#两直线交点 Line_1:[Point_1, Point_2], Line_2:[Point_1, Point_2]
def crossPointOfTwoLine(Line_1, Line_2):
    if not parallelCheck(Line_1, Line_2):
        L1_Point_1, L1_Point_2, L2_Point_1, L2_Point_2 = Line_1[0], Line_1[1], Line_2[0], Line_2[1];
        '''
        k1, k2 = slope(L1_Point_1, L1_Point_2), slope(L2_Point_1, L2_Point_2);

        if (k1 == 'inf'):
            return [L1_Point_1[0], L2_Point_1[1]-k2*(L2_Point_1[0]-L1_Point1[0])];
        elif (K2 == 'inf'):
            return [L2_Point_1[0], L1_Point_1[1]-k1*(L1_Point_1[0]-L2_Point1[0])];
        '''

        x0, y0, x1, y1, x2, y2, x3, y3 = L1_Point_1[0], L1_Point_1[1], L1_Point_2[0], L1_Point_2[1],\
                                         L2_Point_1[0], L2_Point_1[1], L2_Point_2[0], L2_Point_2[1];
        
        crossY = ( (y0-y1)*(y3-y2)*x0 + (y3-y2)*(x1-x0)*y0 + (y1-y0)*(y3-y2)*x2 + (x2-x3)*(y1-y0)*y2 ) / \
                 ( (x1-x0)*(y3-y2) + (y0-y1)*(x3-x2) );
        crossX =  x2 + (x3-x2)*(crossY-y2) / (y3-y2);

        
        return [crossX, crossY];</span>


一个点是不是在已知直线上呢?

<span style="font-size:18px;">#判定三点共线
def pointInLine(Point_1, Point_2, Point_3):
    x0, y0, x1, y1, x2, y2 = Point_1[0], Point_1[1], Point_2[0], Point_2[1], Point_3[0], Point_3[1];

    return (x0*y1-y0*x1)+(x1*y2-y1*x2)+(x2*y0-y2*x0) == 0;</span>


点到直线的距离是多少?

<span style="font-size:18px;">#点到直线的距离
def plDistance2D(Point, Line):
    LPoint_1, LPoint_2 = Line[0], Line[1];

    if (pointInLine(Point, LPoint_1, LPoint_2)):
        return 0;
    else:
        k = slope(LPoint_1, LPoint_2);

        if k == 'inf':
            return abs(Point[0]-LPoint_1[0]);
        else:
            Point2 = [Point[0] + 10, Point[1] + 10 * k];
            return lineDistance2D([Point, Point2], Line);
            </span>

[从头学数学] 第201节 几何证明选讲_第4张图片

[从头学数学] 第201节 几何证明选讲_第5张图片

[从头学数学] 第201节 几何证明选讲_第6张图片

[从头学数学] 第201节 几何证明选讲_第7张图片

[从头学数学] 第201节 几何证明选讲_第8张图片

[从头学数学] 第201节 几何证明选讲_第9张图片

[从头学数学] 第201节 几何证明选讲_第10张图片


说到圆,也有一些东西是小伟想计算出来的。


比如已知圆上三个点,这个圆的圆心在哪,半径多少?

<span style="font-size:18px;">#圆 三点成圆  
#以确定的三点表示圆的方程,得到圆心和半径 [x1, y1] -- [x2, y2] -- [x3, y3]
def circle(Point_1, Point_2, Point_3):
    if not pointInLine(Point_1, Point_2, Point_3):
        x1, y1, x2, y2, x3, y3 = Point_1[0], Point_1[1], Point_2[0], Point_2[1], Point_3[0], Point_3[1];

        A1 = 2*(x2-x1);
        B1 = 2*(y2-y1);
        C1 = x2*x2+y2*y2-x1*x1-y1*y1;   
        A2 = 2*(x3-x2);
        B2 = 2*(y3-y2);
        C2 = x3*x3+y3*y3-x2*x2-y2*y2;

        #圆心
        px = ((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1));  
        py = ((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1));

        a = round(distance2D(Point_1, Point_2), 3);
        b = round(distance2D(Point_2, Point_3), 3); 
        c = round(distance2D(Point_3, Point_1), 3);

        #半径
        R = a*b*c/(4*b*b*c*c-(b*b+c*c-a*a)**2)**0.5;

        return [[px, py], R];
    else:
        return [[0, 0], 0];</span>


一个点是在圆的内部呢,外部呢,圆上呢,怎样知道?

<span style="font-size:18px;">#判断点和圆的距离 Point:[x, y], Circle: [[x1, y1], [x2, y2], [x3, y3]]
def pointFromCircle(Point, Circle):
    cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
    circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

    d = distance2D(Point, circleCenter);

    #点与圆的位置关系,分为在内部,在外部和在圆上。
    if (d < R):
        return 'IN';
    elif (d > R):
        return 'OUT';
    else:
        return 'ON';</span>


从圆外一点引圆的切线,切点在哪?

<span style="font-size:18px;">#过圆外部一点,得到与圆的切点的坐标 Point:[x, y], Circle: [[x1, y1], [x2, y2], [x3, y3]]
def tangencyPoint(Point, Circle):
    if pointFromCircle(Point, Circle) == 'OUT':
        cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
        circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

        x1, y1, x2, y2 = circleCenter[0], circleCenter[1], Point[0], Point[1];

        dsquare = (x2-x1)**2+(y2-y1)**2;

        part_1 = (R*R*(y1-y2)**2*(dsquare-R*R))**0.5;
        part_2 = (y1-y2)*dsquare;

        #第一个切点
        x3 = (-part_1+R*R*(x2-x1)+x1*dsquare)/dsquare;
        y3 = ((x1-x2)*part_1-R*R*(y1-y2)**2+y1*part_2)/part_2;
        #第二个切点
        x4 = (part_1+R*R*(x2-x1)+x1*dsquare)/dsquare;
        y4 = (-(x1-x2)*part_1-R*R*(y1-y2)**2+y1*part_2)/part_2;

        return [[x3, y3], [x4,y4]];

    return [[0,0], [0,0]];</span>


直线和圆的距离是多少呢?

<span style="font-size:18px;">#直线到圆的距离
def lcDistance2D(Line, Circle):
    lPoint_1, lPoint_2 = Line[0], Line[1];
    cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];

    circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

    #圆心到直线的距离
    d = plDistance2D(circleCenter, Line);

    return d-R;</span>


如果直线和圆有交点,在哪?

<span style="font-size:18px;">#直经与圆的交点
def lcCrossPoint2D(Line, Circle):
    #直线与圆相交
    if lcDistance2D(Line, Circle) <= 0:
        lPoint_1, lPoint_2 = Line[0], Line[1];
        cPoint_1, cPoint_2, cPoint_3 = Circle[0], Circle[1], Circle[2];
        circleCenter, R = circle(cPoint_1, cPoint_2, cPoint_3);

        k, a, b = interceptOfLine(lPoint_1, lPoint_2);

        if k == 'inf':
            k = 1e8;

        c, d = -circleCenter[0], -circleCenter[1];

        print(k, a, b, c, d, R);

        part_0 = (k*k+1)*R*R-c*c*k*k;
        part_1 = (2*c*d+ 2*b*c)*k- d*d-2*b*d-b*b;
        part_2 = (d+b)*k+c;
        part_3 = d*k*k-b;
        part_4 = (k*k+1);
        
        x1 = -((part_0 + part_1)**0.5+part_2)/part_4;
        y1 = -(k*((part_0+part_1)**0.5 + c)+part_3)/part_4;

        x2 = ((part_0+part_1)**0.5-part_2)/part_4;
        y2 = (k*((part_0+part_1)**0.5 - c)-part_3)/part_4;

        return [[x1, y1], [x2, y2]];

    return [[1e8, 1e8], [1e8, 1e8]];</span>


[从头学数学] 第201节 几何证明选讲_第11张图片

[从头学数学] 第201节 几何证明选讲_第12张图片

[从头学数学] 第201节 几何证明选讲_第13张图片

[从头学数学] 第201节 几何证明选讲_第14张图片

[从头学数学] 第201节 几何证明选讲_第15张图片

[从头学数学] 第201节 几何证明选讲_第16张图片

本节到此结束,欲知后事如何,请看下回分解。

你可能感兴趣的:([从头学数学] 第201节 几何证明选讲)