Nano Hash - криптовалюты, майнинг, программирование

Как нарисовать часть линии в SVG?

Кто-нибудь знает, можно ли/как провести линию между точками, сохраняя при этом определенное расстояние от конечных точек в SVG?

В случае, если линия горизонтальна (например, от (40,40) до (100,40)), вы можете легко нарисовать линию, которая сохраняет расстояние около 20 до точек следующим образом.

<line x1="40" y1="40" x2="100" y2="40" desc="directional line" />
<line x1="60" y1="40" x2="80" y2="40" desc="actual part of line" />

Однако для диагональных линий это немного сложнее. Чтобы нарисовать (простую) диагональную линию от (40,40) до (100,100), вам потребуется cos(pi/4) = sin(pi/4) = sqrt(2) для масштабирования расстояния, на котором вы хотите держаться подальше от конечной точки (в данном случае: 20*sqrt(2) = 14.1)

<line x1="40" y1="40" x2="100" y2="100" desc="directional line" />
<line x1="54.1" y1="54.1" x2="85.9" y2="85.9" desc="actual part of line" />

Демонстрацию этого кода можно найти в этой скрипте.

Таким образом, представляется возможным сделать это при расчете

  1. Угол между направляющей линией и горизонтальной линией
  2. Синус и косинус угла
  3. Конечные точки фактической части линии, которую вы хотите нарисовать

Это единственный способ, или SVG может указывать части строк, или есть более умные и удобные способы сделать это?

22.01.2017

Ответы:


1

Я не уверен, что это умно или удобно, но один из способов сделать это без скрипта заключается в следующем.

Вы можете использовать прямоугольник в качестве маркера (начало маркера и конец маркера), а с помощью свойств markerWidth и markerHeight в сочетании с шириной штриха линии вы можете контролировать размер маркера.

markerWidth * stroke-width = real width

<svg width="220" height="220">
  <marker id="m1" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="20" refY="3">
    <rect x="0" y="0" width="20" height="6" fill="red" opacity="0.5" />
  </marker>
  <marker id="m2" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="0" refY="3">
    <rect x="0" y="0" width="20" height="6" fill="red" opacity="0.5" />
  </marker>

  <line id="l2" x1="20" y1="20" x2="200" y2="80" marker-end="url(#m1)" marker-start="url(#m2)" stroke="black" stroke-width="2" />

</svg>

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

Но это не совсем то, чего мы хотим. Чтобы действительно «обрезать» линию маркером, вы можете использовать маску. Так что нарисуйте свою линию как маску, с белой обводкой, но с черными маркерами.

примените эту маску к вашей линии (без маркера)... вот и все: линия с видимым штрихом, который имеет фиксированное расстояние до конечных точек.

плюсы: не используется javascript

минусы: приходится дважды рисовать линию

function redraw() {
  var x1 = Math.random() * 200
  var y1 = Math.random() * 200
  var x2 = Math.random() * 200
  var y2 = Math.random() * 200

  l1.setAttribute("x1", x1)
  l1.setAttribute("y1", y1)
  l1.setAttribute("x2", x2)
  l1.setAttribute("y2", y2)

  l2.setAttribute("x1", x1)
  l2.setAttribute("y1", y1)
  l2.setAttribute("x2", x2)
  l2.setAttribute("y2", y2)

  c1.setAttribute("cx", x1)
  c1.setAttribute("cy", y1)
  c2.setAttribute("cx", x2)
  c2.setAttribute("cy", y2)
}
line {
  stroke-width: 2px
}
<svg width="220" height="220">
  <marker id="m1" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="20" refY="3">
    <rect x="0" y="0" width="20" height="6" fill="black" />
  </marker>
  <marker id="m2" orient="auto" viewBox="0 0 20 6" markerWidth="10" markerHeight="3" refX="0" refY="3">
    <rect x="0" y="0" width="20" height="6" fill="black" />
  </marker>
  <mask id="mask">
    <line id="l2" x1="20" y1="20" x2="200" y2="80" marker-end="url(#m1)" marker-start="url(#m2)" stroke="white" />
  </mask>
  <circle id="c1" cx="200" cy="80" r="5" fill="blue" />
  <circle id="c2" cx="20" cy="20" r="5" fill="blue" />
  <line id="l1" x1="20" y1="20" x2="200" y2="80" mask="url(#mask)" stroke="black" />
</svg>

<button onclick="redraw()">redraw</button>

23.01.2017

2

Один из хакерских способов сделать это — это обман с круговым рисунком, масштабированным по размеру вашей линии. Не идеально, но зависит от вашего варианта использования:

<svg width="200" height="200" viewbox="0 0 200 200">
  <defs>
    <pattern id="patt" width="1" height="1" patternContentUnits="objectBoundingBox">
      <rect x="0" y="0" width="1" height="1" fill="cyan" />
      <circle cx=".5" cy=".5" r=".4" fill="blue" />
    </pattern>
  </defs>
  
  <g id="hand-drawn">
    <line x1="40" y1="40" x2="100" y2="100" stroke="red" stroke-width="2" />
    <line x1="54.1" y1="54.1" x2="85.9" y2="85.9" stroke="green" stroke-width="2" />
  </g>
  
  <g id="circle-pattern">
    <line x1="80" y1="60" x2="200" y2="100" stroke="url(#patt)" stroke-width="2" />
    <line x1="150" y1="10" x2="100" y2="120" stroke="url(#patt)" stroke-width="2" />
    <line x1="0" y1="100" x2="150" y2="100" stroke="url(#patt)" stroke-width="2" />
    <line x1="0" y1="100" x2="150" y2="101" stroke="url(#patt)" stroke-width="2" />
  <g>
</svg>

Конечно, это только дает вам возможность показать линию, которая представляет собой определенный % от концов, а не точное значение в пикселях. Надеюсь, это даст вам некоторые идеи.

Обратите внимание, что это немного глючит - это не работает для горизонтальных или вертикальных линий ... вам нужно будет отображать их как прямоугольники или пути и использовать заливку вместо обводки.

23.01.2017
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..