---
title: Точка масштабирования круга | After Effects
description: Как найти Anhor Point круга, изменяя Scale из которого, он полностью совпадет с другим кругом?
image: https://i.imgur.com/MVSvCuN.png
previewImageSize: large
---
<style>
/* img{
border: solid black;
} */
img[loading]:not([src$='#default']){
display: block;
margin: auto;
}
img[loading]:not([src$='#default']):not([width]){
width: 50%;
}
.markdown-body h1{
border-bottom: unset;
}
hr.dots{
all: unset;
display: block;
font-family: 'Rubik';
text-align: center;
font-size: 6px;
letter-spacing: 20px;
line-height: 60px
}
hr.dots:after{
content: '■■■'
}
img[id]{
display:none;
}
</style>
TG: [@antsharrr](https://t.me/antsharrr)
# AE tips | поиск центра окружности
## Предисловие
Задача, конечно, интересная и если не знать математики, решить ее можно лишь "методом тыка", что, собственно, от части и было сделано. Такой вот эмпирический подход дает возможность самому стать на место первооткрывателей геометрических фактов, что также полезно, я считаю.
Однако, я здесь хотел бы обсудить эту же задачу, но подойдя к ней изначально с математической точки зрения, используя ранее полученные результаты древних.
Забегая вперед, сразу отмечу, что при таком расположении окружностей, **не существует** такой такой точки плоскости, масштабируя из которой одну окружность, она полностью перейдет во вторую. Почему это так, разберемся чуть позже, а пока перейдем к решению в общем виде.

Забавно получается на фоне того, что именно это стало причиной возникновения данной задачи.
<hr class=dots>
## Ход решения
Начнем, на первый взгляд, с чего-то, совершенно не имеющего отношения к нашей задаче, но позднее окажется непосредственно связанным с конструкцией окружностей.
<!-- Начнем не совсем с окружностей, но с того, что окажется тесно связанным с ними — биссектрисой угла. -->
Итак, думаю, все себе представляют, что такое угол, но важно, чтобы мы говорили об одном и том же, поэтому дам строгое определение
> **Определение.** *Углом* называется фигура, образованная двумя лучами, выходящими из одной точки
<!-- <div style="height:60px"></div> -->

То есть, угол изначально не имеет ничего общего с *градусами*, что является частым заблуждением. Градусы — лишь единица измерения — числовая характеристика, позволяющая как-то количественно сравнивать углы между собой.
> **Определение.** *Биссектрисой* угла называется луч, выходящий из его вершины и делящий данный угол пополам

Биссектриса обладает таким свойством, что проведя из любой точки на ней перпендикуляры к лучам угла, то они будут равны

Доказывается это утверждение по теореме о подобии треугольников $\Delta OAC$ и $\Delta OBC$ по двум глам: $\angle OAC = \angle OBC = 90^\circ$ — по построению перпендикуляров, $\angle AOC = \angle BOC$ по определению биссектрисы. А поскольку сторона $OC$ является общей для данных двух треугольников, то они равны, а значит и все стороны у них равны.
И тут впервые появляются окружности, которые, кстати, представляют из себя
> **Определение.** *Окружностью* называется геометрическое место точек, равно удаленных от заданной точки — центра окружности.

Все отрезки, соединяющие любую точку отрезка и ее центра, называемые *радиусами*, равны.
<div style="height:10px"></div>
Теперь вернемся на один рисунок назад, к нашей конструкции. Через точки $A$ и $B$ можем провести окружность с центром $C$, причем сделать это можно единственным образом и тогда лучи угла буду касательными к проведенной окружности.
Действительно, так как наикротчайшее расстояние от точки $C$ к лучу $OA$ (аналогично $OB$ ) — это перпендикуляр (который и называется *расстоянием* от точки к прямой), то все остальные отрезки, соединяющие точку $C$ с любой другой точкой луча будут длиннее радиуса, следовательно $A$ и $B$ — таки точки касания и ни в каких других точках окружность не пересекается с углом. Единственность построения окружности через эти точки нетрудно доказать от противного.

<i id="similar-triangles"></i>
А далее ключевой момент в понимании решения. Рассмотрим два теугольника $\Delta OAC$ и $\Delta OA_1C_1$. По теореме о подобии треугольников, так как $\angle AOC=\angle A_1OC_1$ и $\angle OAC = \angle OA_1C_1\; (= 90^\circ)$, то существует $k$ — коэффициент пропорциональности.
<img style="display:inline" src="https://codimd.s3.shivering-isles.com/demo/uploads/02a6da1fb9d19367162f4238b.png" loading="lazy">
<img style="display:inline" src="https://codimd.s3.shivering-isles.com/demo/uploads/02a6da1fb9d19367162f4238c.png" loading="lazy">
Подобие треугольников означает, что отмасшабировав один треугольник в $k$ раз, их можно полностью совместить со вторым. Нетрудно заметить, что в данном случае, треугольники можно совместить без их дополнительного перемещения: достаточно выполнить масштабирование из точки $O$, которая является общей для обоих треугольников.
<div style="height:30px"></div>
> [color=#F6455A] <p style="color:black">А теперь, внимание! Точка $C$ — центр окружности, что была показана ранее, а отрезок $CA$ — ее радиус. Так как увеличение треугольника в $k$ раз значит увеличение каждой его стороны в $k$ раз, то $O$ — такая точка, что увеличивая из нее, отрезки $OC$ и $CA$ будут линейно и равномерно увеличиваться, то есть увеличение окружности будет происходить в равной мере с перемещением ее по биссектрисе.</p>
<div style="height:70px"></div>

Таким образом, искомый annchor point — вершина угла, в который вписаны обе окнужности.
Завершая теоретический разговор, хочется лишь отметить, что такая конструкция является необходимым и достаточным условием существования точки, масштабируя из которой, одна окружность перейдет в другую.
> **Доказательство.** Достаточность очевидна, поскольку мы начали с того, что взяли конкретную точку (вершину угла) и для нее показали такое свойство.
>
> Остается понять только про то, что для любых двух заданных окружностей, если к ним можно провести две общие внешние касательные, тогда точка пересечения этих касательных и будет тем самым anchor point.
> На самом деле, это скрывается в рассуждениях выше, когда вводилась связь между биссектрисой и расстояниями к лучам угла.
>
> Пусть мы нашли две общие внешние касательные, пересекающиеся в точке $O$, тогда, в частности, это касательные и к какой-то одной из них. Вспоминая определение окружности, понимаем, что проведя отрезки в точки касания, они будут равны как радиусы, а тогда по теореме о подобных треугольника, в этот раз поскольку равны стороны: катеты ($AC = BC$) и общая гипотенуза ($OC$), по эти треугольники равны. Это значит, что и соответствующие углы у них равны. В частности, $\angle AOC = \angle BOC$, ну а тогда прямая $OC$ — биссектриса.
> 
<br>
Из этого взаимно однозначного соответствия и следует упомянутое в начале утверждение: если одна окружность полностью лежит в другой, тогда не существует общих касательных к ним, поэтому и искомого anchor point также не существует по доказанному ранее.
Хочется отметить еще один вырожденный случай, когда окружность в точности раны по размеру. В этом случае существуют общие внешние касательные, однако они параллельны, то есть не пересекаются, так что в этом случае также не найдется anchor point.

> [color=#B6C6A4] <p style="color:black"> Наконец, хочется только отметить, что если бы задача стояла найти точку, масштабируя из которой, центр одной окружности совпал с другой, то это **всегда** можно сделать, независимо от размера и расположения окружностей. Более того, для выбранной окружности, которая будет масштабироваться и смещаться, беря абсолютно произвольную точку, за исключением центра выбранной окружности, на прямой, проходящей через центр обоих окружностей, всегда найдется такой коэффициент пропрорциональности $k$, который совместит центры.

</p>
<br>
<hr class=dots>
## Вычисление решения
Нам известны координаты центров окружностей: $C$ и $C_1$, а также их радиусы, которые обозначим как-нибудь для дальнейших вычислений
$$
r_1 = |AC|, \quad r_2 = |A_1C_1|
$$
а также обозначим расстояние между центрами окружностей
$$
d = |CC_1|
$$

Можно сказать, что мы имеем полную информацию о биссектрисе, ведь через две точки (центры окружностей, в нашем случае) проходит единственная прямая. Поэтому, по сути, найдя достаточно информации об одной из касательной, этого будет хватит для нахождения координат $O$, так как эта точка будет точкой пересечения касательной и биссектрисы.
Поскольку мы теперь имеем дело с координатами, нужно ввести координатные оси. Для начала будем считать, что ось $Ox$ проходит как раз через нашу биссектрису.

Из рассуждений [выше](#similar-triangles), мы поняли, что треугольники $\Delta OAC$ и $\Delta OA_1C_1$ — подобны, поэтому существует такое число $k$, что
<i id=similar-ratio></i>
$$
\begin{cases}
|OA_1|=k\cdot|OA| \\
|OC_1| = k\cdot|OC| \\
|A_1C_1|=k\cdot|AC|
\end{cases}
\quad\Rightarrow\quad
\frac{|OA_1|}{|OA|}=k,\enspace
\frac{|OC_1|}{|OC|}=k,\enspace
\frac{|A_1C_1|}{|AC|}=k
$$
в частности
$$
\frac{|OC_1|}{|OC|}=k=\frac{|A_1C_1|}{|AC|}
$$
Заметим, что $|OC_1| = |OC|+|CC_1|$ и вспоминая введенные обозначения, получим
<i id=distance-to-O></i>
$$
\begin{array}{}
&\dfrac{|OC|+d}{|OC|} = \dfrac{r_2}{r_1}
&\Leftrightarrow&
\color{gray}{\dfrac{|OC|}{|OC|}+\dfrac{d}{|OC|} = \dfrac{r_2}{r_1}}
&\color{gray}\Leftrightarrow&
\color{gray}{\dfrac{d}{|OC|} = \dfrac{r_2}{r_1}-1}
&\color{gray}\Leftrightarrow\\
\color{gray}\Leftrightarrow&
\color{gray}{\dfrac{d}{|OC|} = \dfrac{r_2}{r_1}-\dfrac{r_1}{r_1}}
&\color{gray}\Leftrightarrow&
\color{gray}{\dfrac{d}{|OC|} = \dfrac{r_2-r_1}{r_1}}
&\Leftrightarrow&
|OC| = d\cdot\dfrac{r_1}{r_2-r_1} & \quad(*)\hspace{-5ex}
\end{array}
$$
Таким образом, мы нашли длину $|OC|$ и сместившись на это расстояние от центра окружности $C$, мы найдем координаты $O$.
Может показаться, что касательную прямую мы вовсе не задействовали, однако $|OC|$ был найден именно из предположения о том, что существует касательная с точками касания $A$ и $A_1$ и именно из этого предположения мы установили подобие треугольников и, собственно, нашли $|OC|$.
Конечно, можно было бы явно найти координаты точек касания $A$ и $A_1$, написать уравнения биссектрисы и касательной, как прямых проходящих через две точки
<i id=line-equation></i>
$$
\frac{y-y_1}{y_2-y_1} = \frac{x-x_1}{x_2-x_1}
\quad\Leftrightarrow\quad
y = \frac{y_2-y_1}{x_2-x_1}(x-x_1)+y_1 \hspace{15ex}(**)\hspace{-15ex}
$$
затем отыскать аналитически точку пересечения. Но согласитесь, это куда трудозатратнее, чем представленный способ.
<br>
Поскольку изначально, для простоты, мы положили координатную ось на биссектрису, то теперь необходимо учесть произвольное положение конструкции угла с вписанными окружностями.

Пусть $\varphi$ — угол между биссектрисой и координатной осью $Ox$. Обозначим координаты центра как $C = (C_x,C_y)$, тогда, чтобы из точки $C$ попасть в $O$, необходимо к $x$-координате $C$ прибавлять не $|OC|$, а ее проекцию — $|O'C'|$, которая просто вычисляется
$$
|O'C'| = |OC|\cos\varphi
$$
тогда из формулы [$(*)$](#distance-to-O) получим
$$
|O'C'| = |OC|\cos\varphi = d\cdot\dfrac{r_1}{r_2-r_1}\cdot\cos\varphi = d\cos\varphi\cdot\dfrac{r_1}{r_2-r_1} = |C'C'_1|\cdot\dfrac{r_1}{r_2-r_1}
$$
Последнее равенство следует из того, что мы положили $d=|CC_1|$, а умножая на косинус угла наклона прямой, мы получим ничто иное, как проекцию на $Ox$, то есть $|C'C'_1|$.
Теперь встает вопрос, как найти $|C'C'_1|$. Да очень просто! Мы ведь знаем координаты центров окружностей $C=(C_x,C_y)$ и $C_1=(C_{1y},C_{1x})$, но тогда
$$
|C'C'_1| = C_x - C_{1x}
$$
Поэтому, если изначально взять в качестве $d$ — разность $x$-координат центров, тогда по сравнению с формулой для первого случая, ничего не изменится.
<i id="point-on-line"></i>
Итак, мы теперь знаем $x$-координату точки $O=(O_x,O_y)$, которая вычисляется как
$$
O_x = C_x + d\cdot\frac{r_1}{r_2-r_1}
$$
А для нахождения $y$-координаты, наиболее простым способом будет воспользоваться тем, что $O$ лежит на биссектрисе. Так как если $y=f(x)$ — уравнение прямой-биссектрисы, при значении аргумента $O_x$, получим $f(O_x)=O_y$.
По формуле [$(**)$](#line-equation), находим уравнение биссектрисы, проходящая через $C$ и $C_1$
$$
y = f(x) = \frac{C_{1y}-C_y}{C_{2y}-C_y}(x-C_x)+C_y
$$
<br>
<hr class=dots>
<br>
Прежде, чем перейти к реализации этих вычислений в коде, хотелось сделать замечание по поводу того, почему [представленный](https://medium.com/@ae_tips/67a321b5c769#ed76) способ также работает.
## Альтернативное решение
Как и раньше, проведем прямую, проходящую через центры окружностей (как мы уже знаем, это будет биссектриса некоторого угла с вершиной $O$).
И теперь возьмем произвольную точку на окружности $D$ и проведем радиус к ней, после чего проведем радиус второй окружности под таким же углом биссектрисе, что и первый радиус. Тогда радиусы $CD$ и $C_1D_1$ будут параллельны.

Проведем через точки $D$ и $D_1$ прямую. Она пересечет биссектрису в некоторой точки $\widetilde O$.
Мы пока не знаем, что это за точка, поэтому рассмотрим треугольники $\Delta \widetilde ODC$ и $\Delta \widetilde OD_1C_1$. Они подобны по двум углам: $\angle \widetilde OCD = \angle \widetilde OC_1D_1$ и $\angle \widetilde ODC = \angle \widetilde OD_1C_1$ по построению.
А тогда, по абсолютно алогичным рассуждениям [выше](#similar-ratio), получаем, что
$$
\begin{gather}
\frac{|\widetilde OC_1|}{|\widetilde OC|}=\frac{|D_1C_1|}{|DC|}, \quad |D_1C_1| = r_2, \enspace |DC| = r_1, \\
|\widetilde OC_1| = |\widetilde OC| + |CC_1| = |\widetilde OC| + d, \\[1ex]
\frac{|\widetilde OC|+d}{|\widetilde OC|}=\frac{r_2}{r_1}
\end{gather}
$$
но, с другой стороны, до этого, мы [нашли](#distance-to-O), что
$$
\frac{|OC|+d}{|OC|}=\frac{r_2}{r_1}
$$
Отсюда получаем, что
$$
\frac{|\widetilde OC|+d}{|\widetilde OC|}=\frac{r_2}{r_1}=\frac{|OC|+d}{|OC|}
\quad\Rightarrow\quad
|\widetilde OC| = |OC|
\quad\Rightarrow\quad
\widetilde O = O
$$

А поскольку точка $D$ (как и $D_1$) была выбрана произвольно на окружности, получаем справедливость утверждения для всех точек.

Это и доказывает, почему [представленный](https://medium.com/@ae_tips/67a321b5c769#ed76) подход дает также верный результат.
<hr class=dots>
## Реализация решения
В этом разделе мы также напишем скрипт, который будет находить ту самую точку $O$.
Самое главное — большая идея, которая была в [первом разделе](#Ход-решения). Поняв ее, дальше не составит труда выполнить всю арифметику при помощи javascript.
Сперва создадим наипростейшую панельку с кнопкой, на клик по которой привяжем выполнение функции, которая и будет находить и перемещать anchor point.
```javascript=
function moveAnchor(){
```
<div style="margin-bottom:-30px"></div>
```
...
```
<div style="margin-bottom:-30px"></div>
```javascript=31
}
var scriptWindow = new Window("palette{margins: 20}", "Find anchor");
var findButton = scriptWindow.add("button", undefined, "Find");
findButton.onClick = function(){moveAnchor()};
scriptWindow.show()
```
А теперь к главному — описанию функции `moveAnchor`. Обвернем все содержимое в один блок, чтобы все действия функции можно было бы отменить одним действием Undo (Ctrl+Z)
```javascript=2
app.beginUndoGroup("Move anchor to scale-match circles");
```
<div style="margin-bottom:-30px"></div>
```
...
```
<div style="margin-bottom:-30px"></div>
```javascript=30
app.endUndoGroup();
```
Затем в переменную запишем все выделенные слои и выполним проверку, чтобы их было ровно 2. В ином случае прерывать исполнение функции.
```javascript=3
var selLayers = app.project.activeItem.selectedLayers;
if(selLayers.length != 2) return;
```
Получим время плейхеда, которое понадобиться позже, лишь в одном техническом месте.
```javascript=6
var curTime = selLayers[0].containingComp.time;
```
Введем переменные для двух выбранных слоев и далее будем производить вычисления для anchor point первого выбранного слоя.
```javascript=8
var circle1 = selLayers[0];
var circle2 = selLayers[1];
```
Чтобы получить реальный размер слоев, используется метод `sourceRectAtTime`, который принимает два аргумента, первый из которых, как раз таки время. Для этого нам и нужна была ране объявленная переменная `curTime`.
Вообще говоря, если слои расположены в самом начале таймлайна, то можно было просто передать начальное значение времени — 0 и не определять `curTime`.
```javascript=18
var r1 = circle1.sourceRectAtTime(curTime, false).height/2 * factor1;
var r2 = circle2.sourceRectAtTime(curTime, false).height/2 * factor2;
```
Так как круг — симметрическая фигура, то взяв половину высоты слоя, мы получим его радиус.
Внимательный читатель должен был заметить переменные `factor1` и `factor2`, которые не были описаны ранее. Так вот дело в том, что даже используя `sourceRectAtTime`, на него не влияет свойство scale слоя, поэтому необходимо домножить еще на
```javascript=12
var factor1 = circle1.scale.value[1]/100;
var factor2 = circle2.scale.value[1]/100;
```
Теперь найдем координаты центров окружностей.
Это, пожалуй, единственный тонкий момент во всем коде. Все потому, что anchor point и position слоя связаны специальным образом: когда `Anchor Point = [0, 0]`, то мы видим якорную точку в центре круга, а `Position` задает именно ее координаты, поэтому независимо от начального положения anchor point, для получения координат центра, просто вычитаем одно из другого
```javascript=15
var c1 = circle1.position.value - circle1.anchorPoint.value * factor1;
var c2 = circle2.position.value - circle2.anchorPoint.value * factor2;
```
Ну и тут мы видим те самые коэффициенты `factor1` и `factor2`. Мы вынуждены домножать координаты anchor point на процентное значение масштабирования слоя, поскольку пространство слоя, в котором находится anchor point — отдельное координатное пространство, не совпадающее с координатами самой композиции и поэтому свойство scale там не учитывается и мы это указываем непосредственно.
Эта тема заслуживает отдельной большой статьи, вместе с методами преобразования координат `toComp`, `fromComp`, `toCompVec` и прочими. А пока перейдем дальше к коду, где все последующее возникновения `factor1` и `factor2` имеют аналогичную причину.
Назовем расстояние между $x$-координатами центров, как и в наших вычислениях из [второго раздела](#Вычисление-решения).
```javascript=17
var d = (c1-c2)[0];
```
А вот для $|OC|$ введем более простое название
```javascript=20
var q = d*r1/(r2-r1);
```
Координаты точки $O$ — массив, который определим как `origin`.
```javascript=22
var origin = [];
origin[0] = q/factor1;
origin[1] = (c1-c2)[1]/(c1-c2)[0] * origin[0];
```
Здесь `origin[0]` это $O_x$, а `origin[1]` — $O_y$. И $y$-координату мы вычисляем, через $x$-координату. Повторимся, что это связано с тем, что уравнение прямой — функция, принимающая аргумент $x$ и возвращаяющая значение $y$, что было описано [выше](#point-on-line).
Как и говорилось ранее, для реального смещения anchor point, нужно компенсировать сдвиг и в позиции, поэтому имеем следующее
```javascript=26
circle1.anchorPoint.setValue(origin);
circle1.position.setValue(c1 + origin*factor1);
```
Вот, собственно и все. После применения скрипта, при значении scale первого круга, равное значению scale второго, фигуры полностью совпадут.
<div style="width:100%;height:0px;position:relative;padding-bottom:93.628%;"><iframe src="https://streamable.com/e/0yvqp5?loop=0" frameborder="0" width="100%" height="100%" allowfullscreen style="width:100%;height:100%;position:absolute;left:0px;top:0px;overflow:hidden;"></iframe></div>
<div style="height:20px"></div>
Чуть больше десятка строчек чистого кода, которые решают задачу для любого расположения окружностей относительно друг друга, без ненужных проверок. А все потому, что был выбран научный подход к решению — начиная с теории, продолжая аналитическими вычислениями и только потом заканчивая написанием кода.
:::spoiler <span style="font-size:18px;line-height:60px">**Посмотреть код целиком**</span>
```javascript=
function moveAnchor(){
app.beginUndoGroup("Move anchor to scale-match circles");
var selLayers = app.project.activeItem.selectedLayers;
if(selLayers.length != 2) return;
var curTime = selLayers[0].containingComp.time;
var circle1 = selLayers[0];
var circle2 = selLayers[1];
var factor1 = circle1.scale.value[1]/100;
var factor2 = circle2.scale.value[1]/100;
var c1 = circle1.position.value - circle1.anchorPoint.value * factor1;
var c2 = circle2.position.value - circle2.anchorPoint.value * factor2;
var d = (c1-c2)[0];
var r1 = circle1.sourceRectAtTime(curTime, false).height/2 * factor1;
var r2 = circle2.sourceRectAtTime(curTime, false).height/2 * factor2;
var q = r1*d/(r2-r1);
var origin = [];
origin[0] = q/factor1;
origin[1] = (c1-c2)[1]/(c1-c2)[0] * origin[0];
circle1.anchorPoint.setValue(origin);
circle1.position.setValue(c1 + origin*factor1);
app.endUndoGroup();
}
var scriptWindow = new Window("palette{margins: 20}", "Find anchor");
var findButton = scriptWindow.add("button", undefined, "Find");
findButton.onClick = function(){moveAnchor()};
scriptWindow.show()
```
:::
Скачать скрипт: [AS_FindAnchorToMatchCircles.jsx](https://files.fm/down.php?i=d4jdagbd9)
<hr class=dots>
Поскольку кроме простой арифметики, скрипт ничего не делает, то можно было обойтись и экспрешнами, где в качестве нужного расположения будет выступать еще один, в данном случае круг. Это позволяет в реальном времени наблюдать, где должен оказаться anchor point, чтобы совместить два круга.
<div style="width:100%;height:0px;position:relative;padding-bottom:93.628%;"><iframe src="https://streamable.com/e/yoej56?loop=0" frameborder="0" width="100%" height="100%" allowfullscreen style="width:100%;height:100%;position:absolute;left:0px;top:0px;overflow:hidden;"></iframe></div>
<div style="height:20px"></div>
И, по большому счету, код остается идентичным
:::spoiler <span style="font-size:18px;line-height:10px">**Посмотреть код целиком**</span>
```javascript=
circle1 = thisComp.layer("Circle purple");
circle2 = thisComp.layer("Circle orange");
factor1 = circle1.scale[1]/100;
factor2 = circle2.scale[1]/100;
c1 = circle1.position - circle1.anchorPoint * factor1;
c2 = circle2.position - circle2.anchorPoint * factor2;
r1 = circle1.sourceRectAtTime().height/2 * factor1;
r2 = circle2.sourceRectAtTime().height/2 * factor2;
d = (c1-c2)[0];
q = d*r1/(r2-r1);
origin = []
origin[0] = q/factor1;
origin[1] = (c1-c2)[1]/(c1-c2)[0] * origin[0];
c1 + origin*factor1;
```
:::
<div style="height:30px"></div>
Напоследок хочеться отметить, что любую фигуру можно представить помещенной в окружность, поэтому лишь заменив круги из предыдущего примера на другую фигуру, все по-прежнему будет работать, как и задумано.
<div style="width:100%;height:0px;position:relative;padding-bottom:93.628%;"><iframe src="https://streamable.com/e/ihj28x?loop=0" frameborder="0" width="100%" height="100%" allowfullscreen style="width:100%;height:100%;position:absolute;left:0px;top:0px;overflow:hidden;"></iframe></div>
<div style="height:20px"></div>
Скачать проект: [Find_anchor_to_match_circles_(CC (13)).aep](https://files.fm/down.php?i=mfe9hvqjj)
<hr class=dots>
<br>
Спасибо за внимание! Если остались какие-то вопросы, можете задать мне их в телеграм.