Я попытался практически реализовать ответ Роберта Монферы и нашел несколько дополнительных проблем.Я начал вычислять точки сидения многоугольника, как он описал, на осях / соединительных штифтах отдельных звеньев цепи, и все с точно одинаковым расстоянием между ними.
Одна вещь, которая сразу бросается в глаза, если вы посмотритепри этом цепь не является плавной линией.Для человеческого глаза это может выглядеть как единое целое, но описание цепи, вращающейся вокруг шестерни, как дуги окружности, является плохим приближением.
Посмотрите на картинку в вопросе.Правая передача имеет 15 зубьев.Это означает, что угол между соседними звеньями цепи составляет 24 °, а разница в длине между дугой и шнуром от точки к точке (что является конструктивной длиной звена) составляет прибл.0,8%.Звучит не так много, но для ссылки, которую вы рисуете с размером экрана 50 пикселей, это почти половина пикселя.Это разница, которую можно увидеть.
Следующим предложением было использование <marker>
элементов для отдельных звеньев цепи с началом координат в центре между двумя выводами.Так как определенный выше многоугольник имеет свои точки в положении штифтов, для этого необходим второй, который соединяет середины всех сегментов многоугольника.
При реализации этого результирующая цепочка выглядела следующим образом (I 'нарисуйте многоугольник сверху, чтобы проиллюстрировать):
Где «прямая» часть цепочки превращается в «изогнутую», цепочкуссылки серьезно смещены.Причина в том, что ориентация маркера делит пополам входящую и исходящую касательную в вершине.И для прямого участка, и для следования по дуге шестерни, это работает правильно, но там, где оба встречаются, это явно не так.
Чтобы получить правильную ориентацию маркеров, касательные в точкахдолжно соответствовать направлению исходного многоугольника.Роберт предложил провести дугу между точками.Это вероятнее всего сработает, но сложно вычислить правильные радиусы и положения дуги.
Я придумал метод, который дает плавный путь, который выглядит немного кривым, но линия никогда не будет отображаться вконец, и его вычисления действительно просты - я фактически сделал это с листом Excel.
Допустим, у нас есть список точек, отмечающих положения штифтов:
a b c d e f g ...
Есть двавиды ссылок (спереди и сзади), поэтому пометьте каждую другую середину из двух точек:
a b c d e f g ...
ab cd ef
a, ab, c
находятся на прямой линии, так же, как c, cd, d
и так далее.Теперь, если вы нарисуете путь с помощью следующей команды
<path d="M a L ab C b c cd d e ef f g ..." marker-mid="url(#link1)" />
, точка a
не будет содержать маркера, так как его нет в середине.Следующие вершины, которые позиционируют маркеры: ab, cd, ef, ...
, в то время как b, c, d, e, ...
являются контрольными точками кубической кривой Безье.Это означает, что касательная к вершине в ab
- это прямая линия от a
до b
, в cd
от c
до d
и т. Д.
Здесьэто скриншот из Inkscape для иллюстрации:
Другие ссылки можно описать соответственно как
<path d="M b L bc C c d de e f fg g ..." marker-mid="url(#link2)" />
Если вы хотитеПридумайте, можно даже сократить этот бит с помощью команды S
, которая берет контрольную точку перед вершиной и косвенно добавляет свое отражение в качестве следующей контрольной точки после (вычисляются точки e, g, ...
):
<path d="M b L bc C c d de S f fg h hj ..." marker-mid="url(#link2)" />
Для финала Гранд, вот готовый рисунок.Просто ради этого я нарисовал зубья шестерни с помощью той же техники маркеров.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 800 600" width="600" height="450">
<defs>
<marker id="blade1" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
<path style="fill:#ececf4" d="M 16.5,-1.556 13.947,-1.78 A 14,14 0 0 1 -13.947,-1.78 L -16.5,-1.556 0,200 Z" />
<path style="fill:none;stroke:#000" d="M 16.5,-1.556 13.947,-1.78 A 14,14 0 0 1 -13.947,-1.78 L -16.5,-1.556" />
</marker>
<marker id="blade2" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
<path style="fill:#ececf4" d="M 16.5,0.507 13.694,-0.089 A 14,14 0 0 1 -13.694,-0.089 L -16.5,0.507 0,90 Z" />
<path style="fill:none;stroke:#000" d="M 16.5,0.507 13.694,-0.089 A 14,14 0 0 1 -13.694,-0.089 L -16.5,0.507" />
</marker>
<path id="plate" d="M -9.689,-10.392 C -4.782 -7.56 4.782 -7.56 9.689,-10.392 A 12,12 0 1 1 9.689,10.392 C 4.782 7.56 -4.782 7.56 -9.689,10.392 A 12,12 0 1 1 -9.689,-10.392 Z" />
<marker id="link1" style="stroke:#000" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
<use xlink:href="#plate" style="fill:#ddd" />
<circle id="pin" style="fill:#888;stroke:#000" cx="15.689" cy="0" r="4" />
<use xlink:href="#pin" x="-31.378" />
</marker>
<marker id="link2" style="stroke:#000" markerUnits="userSpaceOnUse" orient="auto" overflow="visible">
<use xlink:href="#plate" style="fill:#bbb" />
</marker>
<g id="center1">
<circle r="80" cx="250" cy="300" />
<g id="cq">
<circle r="10" cx="345" cy="265.42" />
<path d="M 252.984,200.049 A 100,100 0 0 1 324.557,233.367 25,25 0 0 0 361.957,200.182 150,150 0 0 0 254.883,150.086 25,25 0 0 0 252.984,200.049 Z" />
</g>
<use xlink:href="#cq" transform="rotate(90 250,300)" />
<use xlink:href="#cq" transform="rotate(180 250,300)" />
<use xlink:href="#cq" transform="rotate(270 250,300)" />
</g>
<mask id="m1">
<rect fill="white" x="50" y="100" width="400" height="400" />
<use xlink:href="#center1" fill="black" />
</mask>
<path id="center2" d="M 647.75 277.2 L 642.04 279.05 L 643.04 282.13 A 20 20 0 0 0 633.31 292.96 L 630.13 292.28 L 628.88 298.15 L 632.06 298.83 A 20 20 0 0 0 636.55 312.68 L 634.38 315.08 L 638.84 319.1 L 641.01 316.69 A 20 20 0 0 0 655.25 319.73 L 656.25 322.8 L 661.96 320.95 L 660.96 317.87 A 20 20 0 0 0 670.7 307.04 L 673.87 307.72 L 675.12 301.85 L 671.94 301.17 A 20 20 0 0 0 667.45 287.32 L 669.62 284.92 L 665.16 280.9 L 662.99 283.31 A 20 20 0 0 0 648.75 280.27 L 647.75 277.2 z" />
<mask id="m2">
<rect fill="white" x="572" y="220" width="160" height="160" />
<use xlink:href="#center2" fill="black" />
</mask>
</defs>
<g mask="url(#m1)">
<path style="fill:none;marker-mid:url(#blade1)" d="M 430,300 427.27,331.26 419.14,361.56 405.88,390 387.89,415.7 365.7,437.89 340,455.88 311.56,469.14 281.26,477.27 250,480 218.74,477.27 188.44,469.14 160,455.88 134.3,437.89 112.11,415.7 94.12,390 80.86,361.56 72.73,331.26 70,300 72.73,268.74 80.86,238.44 94.12,210 112.11,184.3 134.3,162.11 160,144.12 188.44,130.86 218.74,122.73 250,120 281.26,122.73 311.56,130.86 340,144.12 365.7,162.11 387.89,184.3 405.88,210 419.14,238.44 427.27,268.74 430,300 427.27,331.26" />
</g>
<use xlink:href="#center1" style="fill:none;stroke:#000" />
<g mask="url(#m2)">
<path style="fill:none;marker-mid:url(#blade2)" d="M 578.19,315.69 V 284.31 L 590.95,255.65 614.27,234.65 644.11,224.95 675.32,228.23 702.49,243.92 720.94,269.31 727.46,300 720.94,330.69 702.49,356.08 675.32,371.77 644.11,375.05 614.27,365.35 590.95,344.35 578.19,315.69 V 284.31"/>
</g>
<use xlink:href="#center2" style="fill:none;stroke:#000" />
<path style="fill:none;marker-mid:url(#link2)" d="M 281.26 477.27 L 265.63 478.63 C 250 480 218.74 477.27 203.59 473.21 S 160 455.88 147.15 446.89 112.11 415.7 103.11 402.85 80.86 361.56 76.79 346.41 70 300 71.37 284.37 80.86 238.44 87.49 224.22 112.11 184.3 123.21 173.21 160 144.12 174.22 137.49 218.74 122.73 234.37 121.37 281.26 122.73 296.41 126.79 341.88 138.97 357.03 143.03 402.5 155.2 417.66 159.26 463.13 171.43 478.28 175.49 523.75 187.66 538.91 191.72 584.38 203.89 599.54 207.95 645.01 220.12 660.16 224.18 702.49 243.92 711.71 256.61 727.46 300 724.2 315.35 702.49 356.08 688.91 363.92 645.01 379.88 629.85 383.94 584.38 396.11 569.22 400.17 523.75 412.34 508.6 416.4 463.13 428.57 447.97 432.63 402.5 444.8 387.35 448.86 341.88 461.03 326.72 465.09 281.26 477.27 265.63 478.63 L 250 480" />
<path style="fill:none;marker-mid:url(#link1)" d="M 311.56 469.14 L 296.41 473.21 C 281.26 477.27 250 480 234.37 478.63 S 188.44 469.14 174.22 462.51 134.3 437.89 123.21 426.79 94.12 390 87.49 375.78 72.73 331.26 71.37 315.63 72.73 268.74 76.79 253.59 94.12 210 103.11 197.15 134.3 162.11 147.15 153.11 188.44 130.86 203.59 126.79 250 120 265.63 121.37 311.56 130.86 326.72 134.91 372.19 147.08 387.35 151.14 432.82 163.31 447.97 167.37 493.44 179.54 508.6 183.6 554.07 195.77 569.22 199.83 614.69 212 629.85 216.06 675.32 228.23 688.91 236.08 720.94 269.31 724.2 284.65 720.94 330.69 711.71 343.39 675.32 371.77 660.16 375.82 614.69 388 599.54 392.05 554.07 404.23 538.91 408.28 493.44 420.46 478.28 424.51 432.82 436.69 417.66 440.74 372.19 452.92 357.03 456.97 311.56 469.14 296.41 473.21 L 281.26 477.27" />
</svg>