• MATLAB | 三个趣的圆相关的数理性质可视化


    椭圆的准圆

    在这里插入图片描述

    命题1: 椭圆外一点向椭圆做两条切线,若两切线垂直,则点的轨迹为圆形。

    简单说明下为啥:
    对于椭圆 x 2 a 2 + y 2 b 2 = 1 \frac{x^2}{a^2}+\frac{y^2}{b^2}=1 a2x2+b2y2=1,假设其过 ( m , n ) (m,n) (m,n)点的切线方程为 y − n = k ( x − m ) y-n=k(x-m) yn=k(xm),带入得椭圆方程得:

    b 2 x 2 + a 2 ( k 2 ( x − m ) 2 + 2 n k ( x − m ) + n 2 ) − x 2 b 2 = 0 ( a 2 k 2 + b 2 ) x 2 + 2 k a 2 ( n − m k ) x + a 2 ( k m − n ) 2 − a 2 b 2 = 0 b2x2+a2(k2(xm)2+2nk(xm)+n2)x2b2=0(a2k2+b2)x2+2ka2(nmk)x+a2(kmn)2a2b2=0

    b2x2+a2(k2(xm)2+2nk(xm)+n2)x2b2=0(a2k2+b2)x2+2ka2(nmk)x+a2(kmn)2a2b2=0

    由于求的是切线因而 Δ = 0 \Delta=0 Δ=0,即 ( m 2 − a 2 ) k 2 − 2 m n k + n 2 − b 2 (m^2-a^2)k^2-2mnk+n^2-b^2 (m2a2)k22mnk+n2b2,这是一个关于 k k k的约束条件,由伟达定理得到两条切线的斜率 k 1 , k 2 k_1,k_2 k1,k2满足条件:
    k 1 k 2 = n 2 − b 2 m 2 − a 2 k_1k_2=\frac{n^2-b^2}{m^2-a^2} k1k2=m2a2n2b2
    由于两切线垂直,因此 k 1 k 2 = − 1 k_1k_2=-1 k1k2=1,因而有:
    m 2 + n 2 = a 2 + b 2 m^2+n^2=a^2+b^2 m2+n2=a2+b2
    是一个半径为 a 2 + b 2 \sqrt{a^2+b^2} a2+b2 的圆。

    可视化效果:
    在这里插入图片描述

    MATLAB代码:

    function directorC
    % @author : slandarer
    % 公众号  : slandarer随笔
    % 知乎    : hikari
    a=3;b=2;syms k
    % axes基础属性设置
    ax=gca;
    hold on;grid on
    ax.XLim=[-6,6];
    ax.YLim=[-4,4];
    ax.DataAspectRatio=[1,1,1];
    ax.XAxisLocation='origin';
    ax.YAxisLocation='origin';
    ax.LineWidth=1.5;
    ax.XMinorTick='on';
    ax.YMinorTick='on';
    ax.GridLineStyle='-.';
    ax.GridAlpha=.09;
    % 绘制圆和椭圆
    t=linspace(0,2*pi,200);
    plot(a.*cos(t),b.*sin(t),'LineWidth',2.5,'Color',[0,118,168]./255)
    plot(sqrt(a^2+b^2).*cos(t),sqrt(a^2+b^2).*sin(t),'LineWidth',2.5,'Color',[169,64,71]./255)
    % 绘制切线和交点
    thetaList=linspace(0,2*pi,200);
    kline1=plot(0,0,'-.','LineWidth',1.5,'Color',[1,1,1].*.5);
    kline2=plot(0,0,'-.','LineWidth',1.5,'Color',[1,1,1].*.5);
    kpnt=scatter(a,0,'filled','CData',[1,1,1].*.3);
    X=-6:.1:6;
    % 循环绘图
    for i=1:length(thetaList)
        theta=thetaList(i);
        m=sqrt(a^2+b^2).*cos(theta);
        n=sqrt(a^2+b^2).*sin(theta);
        kk=double(solve((m^2-a^2)*k^2-2*m*n*k+n^2-b^2==0)); 
        Y1=kk(1).*(X-m)+n;Y2=kk(2).*(X-m)+n;
        kline1.XData=X;kline1.YData=Y1;
        kline2.XData=X;kline2.YData=Y2;
        kpnt.XData=m;
        kpnt.YData=n;
        drawnow;
        pause(.01)
    end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    旋转的错觉

    命题2: 假设有半径为 r 2 \frac{r}{2} 2r的小圆在半径为 r r r大圆内滚动,小圆上的点轨迹为直线。

    证明很简单,假设此时小圆上有一点与大圆接触,且此时小圆圆心与原点的连线与x轴正方向的夹角为 θ 0 \theta_0 θ0,现假设小圆滚动导致小圆圆心夹角变化 θ \theta θ,由于小圆半径为大圆的一半,因而当滚过相同路程时,小圆上的点的夹角反方向变化 2 θ 2\theta 2θ因而可以求出该小圆上点位置变化参数方程:

    { x = r 2 c o s ( θ 0 + θ ) + r 2 c o s ( θ 0 + θ − 2 θ ) y = r 2 s i n ( θ 0 + θ ) + r 2 s i n ( θ 0 + θ − 2 θ ) ⇒ { x = ( r 2 c o s ( θ ) ) c o s ( θ 0 ) y = ( r 2 c o s ( θ ) ) s i n ( θ 0 ) {x=r2cos(θ0+θ)+r2cos(θ0+θ2θ)y=r2sin(θ0+θ)+r2sin(θ0+θ2θ){x=(r2cos(θ))cos(θ0)y=(r2cos(θ))sin(θ0)

    {x=2rcos(θ0+θ)+2rcos(θ0+θ2θ)y=2rsin(θ0+θ)+2rsin(θ0+θ2θ){x=(2rcos(θ))cos(θ0)y=(2rcos(θ))sin(θ0)

    这不就是一个过原点,角度为 θ 0 \theta_0 θ0的直线嘛,证明完毕,小圆上所有点都走直线,为了可视化看起来好看,这里画几个等分的点搞一些可视化:

    可视化效果:
    在这里插入图片描述
    在这里插入图片描述

    MATLAB代码:

    function PointOnLineInCircle(N)
    % @author : slandarer
    % 公众号  : slandarer随笔
    % 知乎    : hikari
    if nargin<1||N<2
        N=4;
    end
    % 0.2157    0.3765    0.5725
    % 0.3098    0.5059    0.7412
    
    % figure及axes基础属性设置
    fig=gcf;
    fig.Name='PoLiC';
    fig.Position=[50 100 600 600];
    fig.NumberTitle='off';
    fig.MenuBar='none';
    %
    ax=axes(fig);
    ax.Position=[0 0 1 1];
    ax.XLim=[-2.05 2.05];
    ax.YLim=[-2.05 2.05];
    ax.XColor='none';
    ax.YColor='none';
    hold(ax,'on');
    % grid on
    
    thetaB=0;
    thetaS=0;
    
    
    % 绘制直线
    pntsTheta=0:2*pi/N:2*pi;
    for i=1:(length(pntsTheta)-1)
        plot([cos(pntsTheta(i)),cos(pntsTheta(i)+pi)].*2,...
             [sin(pntsTheta(i)),sin(pntsTheta(i)+pi)].*2,...
             'Color',[0.8 0.8 0.8],'LineWidth',1.5)
    end
    if mod(N,2)==0
        for i=1:(length(pntsTheta)-1)
            plot([cos(pntsTheta(i)+2*pi/N/2),cos(pntsTheta(i)+2*pi/N/2+pi)].*2,...
                 [sin(pntsTheta(i)+2*pi/N/2),sin(pntsTheta(i)+2*pi/N/2+pi)].*2,...
                 'Color',[0.8 0.8 0.8],'LineWidth',1.5)
        end
    end
    % 绘制大圆
    tempT=0:0.1:2*pi+0.1;
    CPnts=[cos(tempT);sin(tempT)];
    plot(CPnts(1,:).*2,CPnts(2,:).*2,'Color',[0.2098 0.4059 0.6412],'LineWidth',2);
    % 绘制小圆
    sCircleHdl=plot(cos(thetaB)+CPnts(1,:),sin(thetaB)+CPnts(2,:),...
        'Color',[0.3098 0.5059 0.7412],'LineWidth',2);
    % 绘制正内接多边形
    pntsHdl=plot(cos(pntsTheta+thetaS)+cos(thetaB),...
        sin(pntsTheta+thetaS)+sin(thetaB),...
        'Color',[0.2157 0.3765 0.5725],'LineWidth',2,'Marker','o',...
        'MarkerFaceColor',[0 0 0],'MarkerEdgeColor',[0 0 0],'MarkerSize',6);
    
    patchHdl=fill(cos(pntsTheta(1:end-1)+thetaS)+cos(thetaB),...
                  sin(pntsTheta(1:end-1)+thetaS)+sin(thetaB),...
                  [0.8500 0.3250 0.0980],'EdgeColor','none','FaceAlpha',0.1);
    % 循环绘图
    while 1
        thetaB=thetaB-2*pi/200;
        thetaS=thetaS+2*pi/200;
        sCircleHdl.XData=cos(thetaB)+CPnts(1,:);
        sCircleHdl.YData=sin(thetaB)+CPnts(2,:);
        pntsHdl.XData=cos(pntsTheta+thetaS)+cos(thetaB);
        pntsHdl.YData=sin(pntsTheta+thetaS)+sin(thetaB);
        patchHdl.XData=cos(pntsTheta(1:end-1)+thetaS)+cos(thetaB);
        patchHdl.YData=sin(pntsTheta(1:end-1)+thetaS)+sin(thetaB);
        pause(0.05);
    end
    end 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    李萨如图形

    这个没啥好说的,画图好看就好hiahiahia:

    可视化效果:
    在这里插入图片描述

    MATLAB代码:

    function lissajous
    % @author : slandarer
    % 公众号  : slandarer随笔
    % 知乎    : hikari
    
    % figure及axes基础属性设置
    fig=gcf;
    fig.Position([2,4])=...
    [fig.Position(2)-fig.Position(3)+fig.Position(4),fig.Position(3)];
    %
    ax=gca;hold on
    ax.Color=[102,117,149]./255;
    ax.XColor='none';ax.XLim=[.4,8.6];ax.YTick=[];
    ax.YColor='none';ax.YLim=[.4,8.6];ax.XTick=[];
    ax.DataAspectRatio=[1,1,1];
    ax.InnerPosition=[0,0,1,1];
    
    % 绘制圆圈
    t=linspace(0,2*pi,200)';
    X=cos(t).*0.42;Y=sin(t).*0.42;
    plot(X+ones(1,7),Y+(1:7),'Color',[1,1,1,.7],'LineWidth',2);
    plot(X+(2:8),Y+ones(1,7).*8,'Color',[1,1,1,.7],'LineWidth',2);
    % 绘制点和基础线
    [Xpnt,Ypnt]=meshgrid(2:8,1:7);
    pntHdl=plot(Xpnt+0.42,Ypnt,'Color',[1,1,1],'LineStyle','none',...
        'Marker','o','MarkerFaceColor',[1,1,1]);
    XlineCol=2:8;YlineCol=8.*ones(1,7);
    XlineRow=ones(1,7);YlineRow=1:7;
    lineColHdl=plot([XlineCol;Xpnt(1,:)]+0.42,[YlineCol;Ypnt(1,:)],...
        'Color',[1,1,1,.5],'LineStyle','-.','Marker','o','MarkerFaceColor',[1,1,1]);
    lineRowHdl=plot([XlineRow;Xpnt(:,end)']+0.42,[YlineRow;Ypnt(:,end)'],...
        'Color',[1,1,1,.5],'LineStyle','-.','Marker','o','MarkerFaceColor',[1,1,1]);
    % 绘制折线句柄
    for m=1:7
        for n=1:7
            lineMatHdl(m,n)=plot(Xpnt(n,m),Ypnt(n,m),...
                'Color',[1,1,1,.6],'LineWidth',1.2);
        end
    end
    ratio=1:7;
    thetaList=linspace(0,2*pi,300);
    % 循环绘图
    for i=1:length(thetaList)
        theta=thetaList(i).*ratio;
        tX=cos(theta).*0.42;
        tY=sin(theta).*0.42;
        for j=1:7
            pntHdl(j).XData=Xpnt(:,j)+tX(j);
            pntHdl(j).YData=Ypnt(:,j)+tY(end:-1:1)';
            lineColHdl(j).XData=[XlineCol(j);Xpnt(1,j)]+tX(j);
            lineColHdl(j).YData=[YlineCol(j);Ypnt(1,j)]+[tY(j);tY(7)];
            lineRowHdl(j).XData=[XlineRow(j);Xpnt(j,end)']+[tX(8-j);tX(7)];
            lineRowHdl(j).YData=[YlineRow(j);Ypnt(j,end)']+tY(8-j);
        end
        %
        ttList=thetaList(1:i);
        for m=1:7
            for n=1:7
                lineMatHdl(m,n).XData=cos(ttList.*m).*0.42+Xpnt(n,m);
                lineMatHdl(m,n).YData=sin(ttList.*(8-n)).*0.42+Ypnt(n,m);
            end
        end
        drawnow
        pause(.01)
    end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
  • 相关阅读:
    zabbix部署与监控
    前端练手项目合集40.0个,附源码,2022年最新
    项目采购管理
    使用 Powershell 检索不理解的命令
    java面试题续集(二)
    python查找替换:查找空行,空行前后添加```,```中间添加 # + 空格 + 空行后遇到的第1行文字?
    使用动态住宅代理还能带来哪些好处?
    Codeforces Round 826 (Div. 3) D 遍历暴力求解
    Sublime Text 快捷键大揭秘:成为代码高效能手的必备技巧!
    我屮艸芔茻,mongo居然可以自动删除数据
  • 原文地址:https://blog.csdn.net/slandarer/article/details/125451619