找回密码
 快速注册
搜索
查看: 44|回复: 0

[Julia] 证明Ceva定理

[复制链接]

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2023-3-10 05:56 |阅读模式
Ceva's Theorem
准备工作与这帖相同, 打开Jupyter notebook.
将下面的命令粘贴到Cell, 按Shift+Enter执行:
引入SymPy
  1. using Pkg;
  2. Pkg.activate(".");
  3. Pkg.add("SymPy")
  4. using SymPy
复制代码
定义一些基本的几何对象。
  1. import Base: isequal, ==
  2. abstract type GeoObject end
  3. abstract type GeoShape <: GeoObject end
  4. struct Point <: GeoObject
  5.     x::Number
  6.     y::Number
  7. end
  8. (==)(p1::Point, p2::Point) = p1.x==p2.x && p1.y==p2.y
  9. struct Triangle <: GeoShape
  10.     A::Point
  11.     B::Point
  12.     C::Point
  13. end
  14. Triangle(ax, ay, bx, by, cx, cy) = Triangle(Point(ax, ay), Point(bx, by), Point(cx, cy))
  15. (==)(t1::Triangle, t2::Triangle) = vertices(t1) == vertices(t2)
  16. function vertices(tri::Triangle)
  17.     [tri.A, tri.B, tri.C]
  18. end
  19. struct Edge <: GeoShape
  20.     src::Point
  21.     dst::Point
  22. end
  23. function edges(tri::Triangle)
  24.     elist = Edge[]
  25.     pts = vertices(tri)
  26.     for i in 1:length(pts)-1
  27.         push!(elist, Edge(pts[i], pts[i+1]))
  28.     end
  29.     push!(elist, Edge(pts[length(pts)], pts[1]))
  30.     elist
  31. end
复制代码

计算两点距离的函数
  1. function squaredist(A, B)
  2.     d = (A.x-B.x)^2+(A.y-B.y)^2
  3.     if d isa Sym
  4.         simplify(d)
  5.     else
  6.         d
  7.     end
  8. end;
复制代码

计算两线交点的函数
  1. function concurrent(e1::Edge, e2::Edge)
  2.     @vars x y
  3.     eqs = Sym[]
  4.     for e in [e1,e2]
  5.         eq = (x-e.src.x)*(y-e.dst.y) - (x-e.dst.x)*(y-e.src.y)
  6.         push!(eqs, eq)
  7.     end
  8.     sol = solve(eqs, [x,y])
  9.     if length(sol) == 0
  10.         return nothing
  11.     else
  12.         return Point(simplify(sol[x]), simplify(sol[y]))
  13.     end
  14. end
复制代码

下面的函数ceva(Triangle(A, B, C), O)输出([A, B, C, D, E, F], [BD, DC, CE, EA, AF, FB])
  1. function ceva(tri, O)
  2.     A, B, C = vertices(tri)
  3.     AB, BC, CA = edges(tri)
  4.     AO, BO, CO = [Edge(pt, O) for pt in vertices(tri)]
  5.     D, E, F = [concurrent(epair...) for epair in zip([BC, CA, AB], [AO, BO, CO])]
  6.     # This mean no such points can be found. (This is possible)
  7.     if D == nothing || E == nothing || F == nothing
  8.         return nothing, nothing
  9.     end
  10.     elist = [Edge(pts...) for pts in zip([B, D, C, E, A, F], [D, C, E, A, F, B])]
  11.     ([A, B, C, D, E, F], elist)
  12. end
复制代码

定义线段的 “长度平方”
  1. squarelength(e::Edge) = squaredist(e.src, e.dst)
复制代码

检查六个长度平方满足Ceva等式的函数
  1. function ceva_check(BD, DC, CE, EA, AF, FB)
  2.     eq = Eq(BD*CE*AF, DC*EA*FB)
  3.     N(simplify(eq))
  4. end
复制代码

证明Ceva定理
  1. function ceva_proof()
  2.     @vars bx by cx cy
  3.     A = Point(1, 0); B = Point(bx, by); C = Point(cx, cy); O = Point(0, 0)
  4.     tri = Triangle(A, B, C)
  5.     plist, elist = ceva(tri, O)
  6.     ceva_check(squarelength.(elist)...)
  7. end
复制代码
输出true
Screenshot 2023-03-09 at 22-29-07 Untitled7 - Jupyter Notebook.png

相关帖子

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 15:38

Powered by Discuz!

× 快速回复 返回顶部 返回列表