我对以下内容对应的 Latex 绘图感兴趣:
这是一张描述椭圆体方法(一种凸优化算法)背后思想的图。它是图 8.1线性最优化简介作者为 Bertsimas 和 Tsitsiklis。
我推测这可以用 tikz 或类似的东西来绘制,但我不知道如何做,所以我将不胜感激任何帮助。
编辑:感谢您的反馈。规格如下:
- $\mathbf x_t$ 位于 $E_t$ 的中心
- $\mathbf x_{t + 1}$ 位于 $_E{t + 1}$ 的中心
- 两条线平行
- $E_t$ 的右侧部分已加阴影
- $E_{t + 1}$ 是包含 $E_t$ 阴影部分的最小椭圆体
- $P$ 的确切性质并不重要。我只希望这幅图看起来与书中的图基本相同。
感恩
这是我的最小示例。遗憾的是,尺寸不太正确。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc, arrows}
% \def\myellipse{(5,1) ellipse (4cm and 2cm)}
\begin{document}
\begin{figure}
\centering
% \includegraphics{}
\begin{tikzpicture}[
dot/.style = {outer sep = +0pt, inner sep = +0pt, shape = circle, draw = black, label = {#1}},
% small dot/.style = {minimum size = 1pt, dot = {#1}},
big dot/.style = {minimum size = 2pt, dot = {#1}},
% line join = round, line cap = round, >=triangle 45
]
% \tikz \draw \myellipse;
\draw (0, 0) ellipse (5.5cm and 2cm);
% \node at ($(2, 0)+(75:2 and 1)$) {$E_t$};
\node at (-4, 0.75) {$E_t$};
% \node at (5, 1) {$\mathbf x_t};
% \node at (5, 1) {\textbullet};
\node[ fill = black, big dot = {above right: \(\mathbf x_t\)}] () at (0, 0) {};
\draw (0,0) -- (-2, 4) -- (2, -4) node[right] {$\mathbf a' \mathbf x > \mathbf a' \mathbf x_t$};
\node[ fill = black, big dot = {above right: \(\mathbf x_{t + 1}\)}] () at (1.5, 0.15) {};
\draw (1.5, 0.15) -- (0.75, 1.65) -- (2.25, -1.35) node[above right] {$\mathbf a' \mathbf x > b $};
\end{tikzpicture}
\caption{Caption}
\label{fig:enter-label}
\end{figure}
\end{document}
答案1
这是使用的东西
图书馆
bbox
对于有角度的椭圆/圆弧的精确边界框,calc
对于坐标计算,intersections
用于找到斜线和法向椭圆之间的交点,以及ext.paths.arcto
用于绘制弧线到一个点
也
PGFMath 函数
x_radius
,以及y_radius
更简单的界面来访问存储在键中的值,PGFMath 函数返回六边形角的随机角度,
rangle(i)
找到位于成角度的线上的点的宏
\tikzonline p:a:xy = v;
A通过点页和坐标=五,一些假设和
希望在评论中解释一些其他内容。
此代码已参数化,因此您只需更改 TikZ 图片选项中的值(角度、主椭圆的半径)。但是,由于我懒得做数学运算,所以有角度的椭圆的半径是硬编码的——难道只有一个解决方案吗?
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{bbox, calc, intersections, ext.paths.arcto}
\pgfmathdeclarefunction{x_radius}{0}{\pgfmathparse{\pgfkeysvalueof{/tikz/x radius}}}
\pgfmathdeclarefunction{y_radius}{0}{\pgfmathparse{\pgfkeysvalueof{/tikz/y radius}}}
\def\tikzonline#1:#2:#3=#4;{%
intersection of {#1}--{[shift=({#2}:1)]#1} and
\if x#3#4,0--#4,1\else0,#4--1,#4\fi}
\begin{document}
\begin{tikzpicture}[
x radius=4, y radius=2, every label/.append style={inner sep=+.15em},
declare function={
ang=110;
rangle(\x)=\x*60+rand*5;}, % randomized hexagon angles
]
\coordinate (xt) at (.5, 0) % somewhere
% this finds the points on the line angled 120° through xt
% that has y = ± 1.5 × y radius
coordinate (xt-start) at (\tikzonline xt:ang:y=+1.5*y_radius;)
coordinate (xt-end) at (\tikzonline xt:ang:y=-1.5*y_radius;)
;
% Let's draw the normal ellipse with the given radii
% the path picture is used to fill everything right of the angled line
% but inside the ellipse.
\draw (xt) circle[] [name path=Et][
path picture={
\fill[lightgray] (xt-start) -| (path picture bounding box.east)
|- (xt-end) -- cycle;}];
% draw the angled line
\draw (xt-start) -- (xt-end)
node[right] {$\mathbf{a'x} > \mathbf{a'x}_t$}
[name path=xt];
% find the intersection points between ellipse and angled line
\tikzset{name intersections={of=Et and xt}}
% the intersections are known but the ellipse through those points is not
% guesstimating some radii
% use a precise bezier bounding box for the angled ellipse
\draw[rotate=ang, x radius=3, y radius=2.34, bezier bounding box]
(intersection-1) arc to[small] coordinate (xt+1-) (intersection-2)
arc to[large] coordinate (xt+1+) cycle;
% since the ellipse is angled like the line
% the center of the ellipse is the center
% between the halfway points on those arcs
\draw
coordinate (xt+1) at ($(xt+1-)!.5!(xt+1+)$)
% let's place the other line halfway between the centers
coordinate (2nd) at ($(xt)!.5!(xt+1)$)
(\tikzonline 2nd:ang:y=+.7*y_radius;) coordinate (2nd-start)
-- (\tikzonline 2nd:ang:y=-.7*y_radius;) coordinate (2nd-end)
node [above right] {$\mathbf{a'x} > b$}
% do this in an angled canvas for easier math
[rotate=ang]
% these intersections are randomized corners of the hexagon
% but placed on the parallel line
(intersection of 2nd-start--2nd-end and xt+1--{[shift=(rangle 1:1)]xt+1})
-- plot[samples at = {0, 5, 4, 3}] ([shift={(rangle \x:1)}]xt+1)
-- (intersection of 2nd-start--2nd-end and xt+1--{[shift=(rangle 2:1)]xt+1})
;
% label and draw the points
\node foreach \c/\l in {xt/"$\mathbf x_t$" above right,
xt+1/"$\mathbf x_{t+1}$" below}
[shape=circle, fill, inner sep=+0pt, minimum size=+2.5pt,
style/.expand once=\l] at (\c) {};
\end{tikzpicture}
\end{document}