|
Ceva's Theorem
准备工作与这帖相同, 打开Jupyter notebook.
将下面的命令粘贴到Cell, 按Shift+Enter执行:
引入SymPy
- using Pkg;
- Pkg.activate(".");
- Pkg.add("SymPy")
- using SymPy
复制代码 定义一些基本的几何对象。- import Base: isequal, ==
- abstract type GeoObject end
- abstract type GeoShape <: GeoObject end
- struct Point <: GeoObject
- x::Number
- y::Number
- end
- (==)(p1::Point, p2::Point) = p1.x==p2.x && p1.y==p2.y
- struct Triangle <: GeoShape
- A::Point
- B::Point
- C::Point
- end
- Triangle(ax, ay, bx, by, cx, cy) = Triangle(Point(ax, ay), Point(bx, by), Point(cx, cy))
- (==)(t1::Triangle, t2::Triangle) = vertices(t1) == vertices(t2)
- function vertices(tri::Triangle)
- [tri.A, tri.B, tri.C]
- end
- struct Edge <: GeoShape
- src::Point
- dst::Point
- end
- function edges(tri::Triangle)
- elist = Edge[]
- pts = vertices(tri)
- for i in 1:length(pts)-1
- push!(elist, Edge(pts[i], pts[i+1]))
- end
- push!(elist, Edge(pts[length(pts)], pts[1]))
- elist
- end
复制代码
计算两点距离的函数- function squaredist(A, B)
- d = (A.x-B.x)^2+(A.y-B.y)^2
- if d isa Sym
- simplify(d)
- else
- d
- end
- end;
复制代码
计算两线交点的函数
- function concurrent(e1::Edge, e2::Edge)
- @vars x y
- eqs = Sym[]
- for e in [e1,e2]
- eq = (x-e.src.x)*(y-e.dst.y) - (x-e.dst.x)*(y-e.src.y)
- push!(eqs, eq)
- end
- sol = solve(eqs, [x,y])
- if length(sol) == 0
- return nothing
- else
- return Point(simplify(sol[x]), simplify(sol[y]))
- end
- end
复制代码
下面的函数ceva(Triangle(A, B, C), O) 输出([A, B, C, D, E, F], [BD, DC, CE, EA, AF, FB])
- function ceva(tri, O)
- A, B, C = vertices(tri)
- AB, BC, CA = edges(tri)
- AO, BO, CO = [Edge(pt, O) for pt in vertices(tri)]
- D, E, F = [concurrent(epair...) for epair in zip([BC, CA, AB], [AO, BO, CO])]
- # This mean no such points can be found. (This is possible)
- if D == nothing || E == nothing || F == nothing
- return nothing, nothing
- end
- elist = [Edge(pts...) for pts in zip([B, D, C, E, A, F], [D, C, E, A, F, B])]
- ([A, B, C, D, E, F], elist)
- end
复制代码
定义线段的 “长度平方”
- squarelength(e::Edge) = squaredist(e.src, e.dst)
复制代码
检查六个长度平方满足Ceva等式的函数
- function ceva_check(BD, DC, CE, EA, AF, FB)
- eq = Eq(BD*CE*AF, DC*EA*FB)
- N(simplify(eq))
- end
复制代码
证明Ceva定理- function ceva_proof()
- @vars bx by cx cy
- A = Point(1, 0); B = Point(bx, by); C = Point(cx, cy); O = Point(0, 0)
- tri = Triangle(A, B, C)
- plist, elist = ceva(tri, O)
- ceva_check(squarelength.(elist)...)
- end
复制代码 输出true
|
|