在SASS中,围绕给定x个固定直径的圆定位圆

在SASS中,围绕给定x个固定直径的圆定位圆,sass,trigonometry,Sass,Trigonometry,问题分为两部分: 最终目标是这样的,ala graph DB Visualizers——但使用html/css/sass 第1部分:如何在一个圆周围放置x个圆,使边接触(或者最好是有一点空白)。 举个例子,这就是给定的3,6和7圈。 我正在尝试使用SASS使其正常工作,但是如果有一个库或其他东西可以实现我想要的功能,我宁愿使用它-我只是在努力制定搜索短语 我使用的是trig函数,从中窃取了圆的排列 到目前为止我所拥有的一切 我的数学不好,但是一些朋友给了我一个公式,你可以在下面找到,这个公式

问题分为两部分:

最终目标是这样的,ala graph DB Visualizers——但使用html/css/sass

第1部分:如何在一个圆周围放置x个圆,使边接触(或者最好是有一点空白)。 举个例子,这就是给定的3,6和7圈。 我正在尝试使用SASS使其正常工作,但是如果有一个库或其他东西可以实现我想要的功能,我宁愿使用它-我只是在努力制定搜索短语

我使用的是trig函数,从中窃取了圆的排列

到目前为止我所拥有的一切

我的数学不好,但是一些朋友给了我一个公式,你可以在下面找到,这个公式可以算出到外圆心的距离<代码>$distance:tan((180-($angle))/2)*$radius。然而它并没有像我期望的那样-给定6个圆,直径为100,我期望输出为100,但我得到86.602

下面是一些讽刺——不过在代码笔中可能更容易找到

      @function strip-unit($number) {
        @if type-of($number) == 'number' and not unitless($number) {
          @return $number / ($number * 0 + 1);
        }
        @return $number;
      }

    @mixin on-circle($item-count, $circle-size, $item-size, $break-at) {
      position: relative;
      height: $circle-size;
      padding: 0;
      border-radius: 50%;
      list-style: none;

      >* {
        display: block;
        position: absolute;
        top: 50%;
        left: 50%;
        width: $item-size;
        height: $item-size;
        margin: -($item-size / 2);

        $angle: (360 / $break-at);
        $rot: 0;
        $prevLayer: 0;

        @for $i from 1 through $item-count {
          $layer: ceil($i/ $break-at);
          $layerMinusOne: $layer - 1;
          // MoveX figured out by aligning stuff by eye
          // item-count 3   4   5   6   7   8   9   10 ...12    13   14...20
          // moveX (%)  57  70  85 100  115 130 145 160   192   207  225  315
          $item-radius: strip-unit($item-size) / 2;

          // !! This is where i'm having trouble
          $distance: tan((180-($angle * 1deg))/2) * $item-radius;
          @debug "tan((180-#{$angle})/2) * #{$item-radius} = #{$distance}";

          $moveX: ( $distance / strip-unit($item-size)) * 100 * 1%;
          @debug "moveX: #{$moveX}";

          @if $layer != $prevLayer {
            $prevLayer: $layer;
            $rot: $rot + $angle/2;
          }

          &:nth-of-type(#{$i}) {
            transform:
             // !! This is where the 'percent of circle diameter' measurements come in, translateX uses the size of the element being transformed when % is used. 
              rotate($rot * 1deg) translateX($moveX * $layer) rotate($rot * -1deg);
          }
          $rot: $rot+$angle;
        }
      }
    }

    $numOfCircles: 3; // <- Change me in the codepen 
    .circle-container {
      @include on-circle($item-count: 28, $circle-size: 200px, $item-size: 50px, 
    $break-at: $numOfCircles);
      margin: 5em auto 5em;
      border: solid 5px red;

      .around-a-circle {
        text-align: center;
        border-radius: 50%;
        border: solid 1px #118be1;
      }
    }

上面的代码主要是这样做的,但是间距没有优化,与我的最终目标照片相比,空白太多

距离需要在圆心1和圆心2之间,这是所有圆的半径的一半

我不知道sass,所以这里有一个工作的JS版本作为证明

如果将第32-33行从

var x1 = pointXY[0].x;
var y1 = pointXY[0].y;

您将复制当前正在执行的操作,这将导致重叠的圆圈

*****增加*****

第二、第三、第四级气泡的工作方式将随着圆半径的增大而变大

这样不行

我有一些东西,但需要工作,但我有这个到目前为止

我认为对于每一行,你需要两组不同的公式才能完美地工作,第二行可以工作,第三行不行,这就是需要新公式的地方。我会回到这一点上

这似乎有效:

你必须记录一对相邻的泡泡,并在其旁边附加泡泡。如果你把气泡9和15的坐标放在堆栈上,它会把新的气泡完美地放在它旁边。但是,不能将气泡9和16也放在堆栈上,因为这会导致重叠。有一系列配对是安全的,可能在某些级别上是一致的,我怀疑奇偶级别有不同的配对规则


实际上,仔细想想,只需对9,15和9,16进行处理,如果屏幕上的两个圆之间存在重叠,则将其丢弃,然后尝试下一对。

感谢您的回答,此解决方案将红色大圆半径作为输入,并计算出较小圆的半径。理想情况下,我只想定义较小圆的大小,并计算出其他所有圆相对于这个圆的位置。。。这是可能的吗?将最终输出缩放到您想要的大小-对上一个小提琴进行了轻微调整-请参见更改第一行以设置所需的圆半径。对于红色圆圈,您可以删除对它的所有引用,包括变量。var x=数学cos(弧度)*红圈;将变为var x=数学cos(弧度);红色的圆圈只是为了我的参考,看看它是如何使用你的答案和一些摆弄,我已经设法在SASS中实现了你的建议,这与你的JS版本一样有效(有轻微重叠的圆圈等等)。这是一个添加了分层的版本()-我可能会在这个阶段放弃第2部分!谢谢你的帮助
var x1 = pointXY[0].x;
var y1 = pointXY[0].y;
var x1 = xPos;
var y1 = yPos;