找回密码
 快速注册
搜索
查看: 60|回复: 19

MMA 如何简便地输出极线方程?

[复制链接]

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

kuing 发表于 2024-3-21 18:22 |阅读模式
本帖最后由 kuing 于 2024-3-21 18:33 编辑 我们知道二次曲线的极线方程是有规律的,一般就是将二次曲线的 `x^2` 变成 `x_0x`,`x` 变成 `(x_0+x)/2`,`xy` 变成 `(x_0y+y_0x)/2`。

在 MMA 里如何实现极线方程的快速输出?

比如定义一个函数 JX,只要输入 JX[某二次曲线,x0,y0] 就输出极线方程?

最近经常撸涉及极点极线的东东,每次都手工输入极线感觉略为麻烦,所以有这一问。

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-21 19:11
先齐次化,Total derivative 把dx、dy、dz換成x0、y0、1,把z換成1,再除2
如,Dt[x^2]輸出2x dx,換掉dx,dy,dz变成 2x x0,再除2
如,Dt[xy]輸出x dy + y dx,換掉dx,dy,dz变成 x y0 + x0 y,再除2
又如,x齐次化变成xz,Dt[xz]輸出x dz+z dx,換掉dx,dy,dz变成 x + x0,再除2

点评

学习鸟  发表于 2024-3-21 22:09

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-21 19:25
例如$x^2+y^2+y+x$
$x^2+y^2+y z+z x$
  1. Dt[x^2+y^2+y z+z x]/.{Dt[x]->x0,Dt[y]->y0,Dt[z]->1,z->1}
复制代码

輸出 x+x0+2 x x0+y+y0+2 y y0
再除以2
\[x \text{ x0}+\frac{x+\text{x0}}{2}+y \text{ y0}+\frac{y+\text{y0}}{2}\]

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-21 22:06
我想到一种办法:
先用 CoefficientList 把系数都提出来,然后乘以改变后的项,再把它们加起来。

代码如下:
  1. CoefficientList[
  2.    a x^2 + b x y + c y^2 + d x + e y + f, {x, y}]*{{1, (y0 + y)/2,
  3.     y0 y}, {(x0 + x)/2, (x0 y + y0 x)/2, 0}, {x0 x, 0, 0}};
  4. Total[%, 2]
复制代码

输出:
f + a x x0 + 1/2 d (x + x0) + c y y0 + 1/2 e (y + y0) +
1/2 b (x0 y + x y0)

如何将它定义为一个函数以便使用?@hbghlyj

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-21 22:30
本帖最后由 kuing 于 2024-3-21 22:37 编辑 我还发现,`(x_0,y_0)` 关于二次曲线 `F(x,y)=0` 的极线方程可以写成
\[F(x,y)-\frac12\left(\frac{\partial F(x,y)}{\partial x}(x-x_0)+\frac{\partial F(x,y)}{\partial y}(y-y_0)\right)=0.\]

代码验证:
  1. F[x_, y_] = a x^2 + b x y + c y^2 + d x + e y + f;
  2. F[x, y] - (D[F[x, y], x] (x - x0) + D[F[x, y], y] (y - y0))/2 // Expand
复制代码

输出:
f + (d x)/2 + (d x0)/2 + a x x0 + (e y)/2 + (b x0 y)/2 + (e y0)/2 + (b x y0)/2 + c y y0

830

主题

4862

回帖

3万

积分

积分
36159

显示全部楼层

isee 发表于 2024-3-21 22:47
kuing 发表于 2024-3-21 22:30
我还发现,`(x_0,y_0)` 关于二次曲线 `F(x,y)=0` 的极线方程可以写成
\[F(x,y)-\frac12\left(\frac{\partia ...


搞不好这就是本质,随便猜的,勿全信

PS: mathematica 真是强,功能太多,忘得快~

点评

我也是随便乱撞的😄  发表于 2024-3-21 22:56
isee=freeMaths@知乎

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-21 23:04
hbghlyj 发表于 2024-3-21 19:11
先齐次化,Total derivative 把dx、dy、dz換成x0、y0、1,把z換成1,再除2
如,Dt[x^2]輸出2x dx,換掉dx,d ...


这种方法如果曲线方程带参数就会多出很多东西呀,得全部替换掉……

比如:
  1. Dt[a x^2 + b x y + c y^2 + d x z + e y z + f z^2] /. {Dt[x] -> x0,
  2.   Dt[y] -> y0, Dt[z] -> 1, z -> 1, Dt[a] -> 0, Dt[b] -> 0, Dt[c] -> 0,
  3.    Dt[d] -> 0, Dt[e] -> 0, Dt[f] -> 0}
复制代码

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-21 23:21
emmmm... 2# 3# 的方法还是有个重要好处的,那就是可以保持形式,最贴合写法的规律。

上面一直都是用完全展开的式子来说的,但有些已经整理好的式子,比如说
\[(a x + b y + c)^2 + (d x + e y + f) (g x + h y + i)=0,\]
在写 `(x_0,y_0)` 的极线时并不需要展开,直接就写出是
\[(a x_0 + b y_0 + c)(a x + b y + c) + \frac12[(d x_0 + e y_0 + f) (g x + h y + i)+(d x + e y + f) (g x_0 + h y_0 + i)]=0.\]
只有用 2# 3# 的方法能达到这效果:
  1. Dt[(a x + b y + c z)^2 + (d x + e y + f z) (g x + h y + i z)] /. {Dt[
  2.     x] -> x0, Dt[y] -> y0, Dt[z] -> 1, z -> 1, Dt[a] -> 0, Dt[b] -> 0,
  3.    Dt[c] -> 0, Dt[d] -> 0, Dt[e] -> 0, Dt[f] -> 0, Dt[g] -> 0,
  4.   Dt[h] -> 0, Dt[i] -> 0}
复制代码

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-22 00:10
kuing 发表于 2024-3-21 15:04
这种方法如果曲线方程带参数就会多出很多东西呀,得全部替换掉……

比如:


或者把x,y,z写成t的函数,再对t偏导:
  1. D[a x[t]^2 + b x[t] y[t] + c y[t]^2 + d x[t] z[t] + e y[t] z[t] + f z[t]^2,t] /. {
  2. x'[t] -> x0, y'[t] -> y0, z'[t] -> 1,
  3. x[t] -> x, y[t] -> y, z[t] -> 1}
复制代码

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-22 00:17
hbghlyj 发表于 2024-3-22 00:10
或者把x,y,z写成t的函数,再对t偏导:


也行,只不过,总感觉有点儿麻烦。
还是得封装成一个函数,才能方便,可惜我不会……

点评

可以另存为Notebook文件🙂  发表于 2024-3-22 00:26

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-22 00:25
hbghlyj 发表于 2024-3-21 11:11
先齐次化,Total derivative 把dx、dy、dz換成x0、y0、1,把z換成1,再除2


三次曲线也能这样做吗?

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2024-3-22 00:51
点评  hbghlyj  可以另存为Notebook文件🙂  发表于 2024-3-22 00:26

这和我说的封装函数有何关联?

点评

可以方便下次使用  发表于 2024-3-22 02:36

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-22 02:42
`(x_0,y_0,z_0)` 关于二次曲线 `F(x,y,z)=0` 的极线方程可以写成
\[\frac{\partial F}{\partial x}x_0+\frac{\partial F}{\partial y}y_0+\frac{\partial F}{\partial z}z_0=0\]

3149

主题

8386

回帖

6万

积分

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

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-3-22 02:43
hbghlyj 发表于 2024-3-21 18:42
`(x_0,y_0,z_0)` 关于二次曲线 `F(x,y,z)=0` 的极线方程可以写成
\[\frac{\partial F}{\partial x}x_0+\frac{\partial F}{\partial y}y_0+\frac{\partial F}{\partial z}z_0=0\]

  1. F = a x^2 + b x y + c y^2 + d x z + e y z + f z^2;
  2. D[F, x] x0 + D[F, y] y0 + D[F, z] z0
复制代码

输出 $2 a x\ \text{x0}+b x\ \text{y0}+b\ \text{x0} y+2 c y\ \text{y0}+d x\ \text{z0}+d\ \text{x0} z+e y\ \text{z0}+e\ \text{y0} z+2 f z\ \text{z0}$

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-3-22 19:56
kuing 发表于 2024-3-22 00:17
也行,只不过,总感觉有点儿麻烦。
还是得封装成一个函数,才能方便,可惜我不会…… ...

就是在Mathematica里写好一个函数,比如函数名叫MyPolar,然后运行:
Save["D:\\mypolar.wl", MyPolar]

就能把那个函数保存到文件里了,然后用的时候Get["D:\\mypolar.wl"],就能运行那个函数了。

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-3-22 20:00
本帖最后由 abababa 于 2024-3-22 20:07 编辑
kuing 发表于 2024-3-21 22:30
我还发现,`(x_0,y_0)` 关于二次曲线 `F(x,y)=0` 的极线方程可以写成
\[F(x,y)-\frac12\left(\frac{\partia ...


我还是在学Asymptote的时候,网友给提供了一个求二次曲线的极点极线的命令,然后照着那个命令,我写了一个Mathematica的:
  1. MyPolar[f_, point_] := Module[{},
  2. AA := Coefficient[f, x, 2];
  3. BB := Coefficient[f, x*y, 1];
  4. CC := Coefficient[f, y, 2];
  5. g := f - (AA*x^2 + BB*x*y + CC*y^2);
  6. DD := Coefficient[g, x, 1];
  7. EE := Coefficient[g, y, 1];
  8. FF := g - (DD*x + EE*y);
  9. xx := point[[1]];
  10. yy := point[[2]];
  11. Return[FullSimplify[(2*AA*xx + BB*yy + DD)*x + (BB*xx + 2*CC*yy + EE)*y + (DD*xx*xx + EE*yy*yy + 2*FF)]];
  12. ]
复制代码


我写的上面的这个代码,要求第一个参数必须是x,y的表达式,并且必须是二次曲线的那种,如果不是二次曲线的就不行了,用u,v的表达式也不行,我想把它弄成像求导的像D[y^2,y,2]这样的,就是可以自己指定对什么东西求导,这样的话,再定义一个参数叫args_的,然后用的时候像MyPolar[u^2+v^2-1,{u,v},{0,1}]这样的,就能解决表达式的问题了,但这个我不会。
网友提供的那两个命令如下:
  1. /**
  2. * 取得点 p 关于圆锥曲线 c 的极线
  3. * @point p 点 p
  4. * @conic c 圆锥曲线 c
  5. * @return 返回点 p 关于圆锥曲线 c 的极线
  6. */
  7. line polar(point p, conic c) {
  8.         bqe obqe = equation(c);
  9.         real A = obqe.a[0], B = obqe.a[1], C = obqe.a[2], D = obqe.a[3], E = obqe.a[4], F = obqe.a[5];
  10.         real x = p.x, y = p.y;
  11.         return line((2*A*x+B*y+D), (B*x+2*C*y+E), (D*x+E*y+2*F));
  12. }
  13. /**
  14. * 取得直线 l 关于圆锥曲线 c 的极点
  15. * @line l 直线 l
  16. * @conic c 圆锥曲线 c
  17. * @return 返回直线 l 关于圆锥曲线 c 的极点
  18. */
  19. point pole(line l, conic c) {
  20.         bqe obqe = equation(c);
  21.         real A = obqe.a[0], B = obqe.a[1], C = obqe.a[2], D = obqe.a[3], E = obqe.a[4], F = obqe.a[5];
  22.         real a = l.a, b = l.b, c =l.c;
  23.         real m = a*(B*E-2*C*D)+b*(B*D-2*A*E)+c*(4*A*C-B*B);
  24.         point p = ((a*(4*C*F-E*E)+b*(D*E-2*B*F)+c*(B*E-2*C*D))/m, (a*(D*E-2*B*F)+b*(4*A*F-D*D)+c*(B*D-2*A*E))/m);
  25.         return p;
  26. }
复制代码

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

GMT+8, 2025-3-4 12:02

Powered by Discuz!

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