命题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)
y−n=k(x−m),带入得椭圆方程得:
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(x−m)2+2nk(x−m)+n2)−x2b2=0(a2k2+b2)x2+2ka2(n−mk)x+a2(km−n)2−a2b2=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
(m2−a2)k2−2mnk+n2−b2,这是一个关于
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=m2−a2n2−b2
由于两切线垂直,因此
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
命题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)
这不就是一个过原点,角度为 θ 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
这个没啥好说的,画图好看就好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