Geometry 基于半径计算三个接触圆的位置

Geometry 基于半径计算三个接触圆的位置,geometry,raphael,Geometry,Raphael,这最终是一个几何问题。我正在使用raphaeljs为一系列数据中的每个项目绘制3个面积圆。每个圆圈表示类别中的项目数 我希望圆圈接触,但不重叠,我希望整组集中在其母div的中间。 图表如下: 如果只知道每个圆的半径以及父div的宽度和高度,我将如何计算每个圆中心的xy坐标?我想得越多,我想我实际上是在试图画一个三角形,其中每个角都是圆的x,y中心。除了最初的问题之外,你还需要限制或选择一些约束条件。在您的示例图像中,您是如何决定旋转由中心形成的三角形的?三角形的“中心”叫什么 一种方法可能是:

这最终是一个几何问题。我正在使用raphaeljs为一系列数据中的每个项目绘制3个面积圆。每个圆圈表示类别中的项目数

<>我希望圆圈接触,但不重叠,我希望整组集中在其母div的中间。

图表如下:


如果只知道每个圆的半径以及父div的宽度和高度,我将如何计算每个圆中心的xy坐标?我想得越多,我想我实际上是在试图画一个三角形,其中每个角都是圆的x,y中心。

除了最初的问题之外,你还需要限制或选择一些约束条件。在您的示例图像中,您是如何决定旋转由中心形成的三角形的?三角形的“中心”叫什么

一种方法可能是:

假设第一个圆位于原点(0,0) 假设第二个圆位于该点正上方(0,r1+r2) 计算第三点-这是两个圆的交点。一个以原点为中心,半径为r1+r3,另一个以(0,r1+r2)为中心,半径为r2+r3

现在你有了这三个点,你可以计算一个“中心”

然后你可以根据这个中心和你的div的尺寸画圆。

这就是问题所在。您可以使用链接找到解决方案

我已经做过这个的迭代推广。给定两条彼此相切的曲线A和B,变换第三条曲线C,使其与其他两条曲线相切。用户以在两条固定曲线上选择点的形式提供一些提示。算法如下所示:

  • 设p和q为投影到A和B上的选定点
  • 变换C,使其与p和q相关联
  • 因为我们不期望C在p和q处与A和B相切,所以我们需要找到p和q的新选择
  • 计算在这些点相交的曲线在p和q处的密切圆(或曲率为0的直线)
  • 计算圆(和线)之间相交的弦
  • 将p和q作为弦中点在A和B上的投影,从2开始重复,直到相交的弦足够小
  • 当然有很多细微的细节,但是任何能够实现这个算法的人都应该能够解决这些问题


    我很快会添加一个说明,但我目前无法访问Mathematica。

    这是我解决这个问题的方法的实现。 它包含了许多几何体和trig标识,但没有调用trig函数

    HTML >>>
    <!DOCTYPE HTML>
    <html>
      <head>
        <title>
          Tangent Circles in a Box
        </title>
        <link rel="stylesheet" href="CSS/tangent_circles.css" type="text/css" />
      </head>
      <body>
        <div id="main_container">
          <div id="inner_container">
            <img class="circle" id="left_circle" src="http://www.clker.com/cliparts/Z/Z/S/Y/S/w/red-circle-cross-transparent-background-md.png" alt="left_circle" />
            <img class="circle" id="right_circle" src="http://www.clker.com/cliparts/Z/Z/S/Y/S/w/red-circle-cross-transparent-background-md.png" alt="right_circle" />
            <img class="circle" id="third_circle" src="http://www.clker.com/cliparts/Z/Z/S/Y/S/w/red-circle-cross-transparent-background-md.png" alt="third_circle" />
          </div>
        </div>
        <div id="userControls">
          <form id="userControlsForm">
            Circle One <input id="circleOneInput" type="text" placeholder="Enter Numeric Value" value=""><br>
            Circle Two <input id="circleTwoInput" type="text" placeholder="Enter Numeric Value" value=""><br>
            Circle Three <input id="circleThreeInput" type="text" placeholder="Enter Numeric Value" value="">
            <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
            <script src="JS/tangent_circles.js"></script> 
          </form>
        </div>
      </body>
    </html>
    HTML <<<
    
    CSS >>>
    body 
    {
      background-color: white;
    }
    
    #main_container
    {
      background-color: #cccccc;
      width: 800px;
      height: 800px;
      margin: auto;
      border: solid #cccccc 1px;
      -o-border-radius: 4px;
      -moz-border-radius: 4px;
      -webkit-border-radius: 4px;
      border-radius: 4px;
    }   
    
      #inner_container 
      {     
        width: 100%;
        height: 100%;
        position: relative;
      }   
    
        .circle
        {
          position: absolute;
          text-align: center;
          font-family: fantasy;
        }
            #left_circle
        {
          top: 0px;
          left: 0px;
          width: 300px;
          height: 300px;
        }
    
        #right_circle
        {
          top: 0px;
          left: 0px;
          width: 300px;
          height: 300px;
        }
    
        #third_circle
        {
          top: 0px;
          left: 0px;
          width: 300px;
          height: 300px;
        }
    
        #userControls
        {
          padding: 30px;
          width: 400px;
          height: 200px;
          margin: auto;
          margin-top: 30px;
          background-color: #dddddd;
        }
    
          #circleOneInput
          {
            margin-bottom: 10px;
          }
    
          #circleTwoInput
          {
            margin-bottom: 10px;
          }
    
    #userControls
    {
      position: absolute;
      left    : 20px;
      top     : 50px;
      width   : 200px;
    }
    CSS <<<
     JS >>>
    $(function() {
      function changeCircles(){
        $("#inputWarning").remove();
        var radius1 = parseInt( $("#circleOneInput").val(), 10);
        var radius2 = parseInt( $("#circleTwoInput").val(), 10);
        var radius3 = parseInt( $("#circleThreeInput").val(), 10);
        console.log( 'radius1 = ' + radius1 + ', ' +
                     'radius2 = ' + radius2 + ', ' +
                     'radius3 = ' + radius3
          );
        if ( isNaN( radius1 ) || isNaN( radius2 ) || isNaN( radius3 ))
        {
          $("#userControlsForm").after('<span id="inputWarning" style="color: red;">Only Numbers Please</span>');
        }
        else
        { 
          // normalize circle sizes
    
          if (radius1 < 10)
          {
            radius1 = 10;
          }
    
          if (radius2 < 10)
          {
            radius2 = 10;
          }
    
          if (radius3 < 10) 
          {
            radius3 = 10;
          }
    
          if (radius1 > 150)
          {
            radius1 = 150;
          }
    
          if (radius2 > 150)
          {
            radius2 = 150;
          }
    
          if (radius3 > 150)
          {   
            radius3 = 150;
          } 
    
          // do the actual circle changing
          // 1) calculate
          // 2) animate
          // calculate sides of triangle
          var a = radius2 + radius3;
          var b = radius1 + radius3;
          var c = radius2 + radius1;
    
          // get dimensions of containing div
          var container_width  = $("#inner_container").width();
          var container_height = $("#inner_container").height();
    
          var center_x = container_width / 2.0;
          var center_y = container_height / 2.0;
    
          // calculate cosine and sine of angle inside circle b
          var cos_beta = ((a * a) + (c * c) - (b * b))/(2 * a * c);
          var sin_beta = Math.sqrt( 1 - cos_beta * cos_beta );
    
          // calculate coordinates of circles a and b
          var Ax = 0;
          var Ay = 0;
          var Bx = radius1 + radius2;
          var By = 0;
    
          // calculate cosine and sine of angle between triangle and horizontal
          var cos_phi = (Bx - Ax)/c;
          var sin_phi = Math.sqrt( 1 - cos_phi * cos_phi );
    
          // calculate the cosine and sine of the sum of both angles
          var cos_phiNbeta = cos_phi * cos_beta - sin_beta * sin_phi;
          var sin_phiNbeta = cos_phi * sin_beta + sin_phi * cos_beta;
    
          // calculate coordinates of circle c
          var Cx = Bx - cos_phiNbeta * a;
          var Cy = By + sin_phiNbeta * a;
    
          // find centroid
          var centroid_x = (Ax + Bx + Cx) / 3.0;
          var centroid_y = (Ay + By + Cy) / 3.0;
    
          // get coordinate adjustment
          var adjust_x = center_x - centroid_x;
          var adjust_y = center_y - centroid_y;
    
          // convert coordinates to div position values
          var A_left = Ax + adjust_x - radius1;
          var A_top  = Ay + adjust_y - radius1;
          var B_left = Bx + adjust_x - radius2;
          var B_top  = By + adjust_y - radius2;
          var C_left = Cx + adjust_x - radius3;
          var C_top  = Cy + adjust_y - radius3;
    
          // calculate div dimensions
          var A_width  = 2 * radius1;
          var A_height = 2 * radius1;
          var B_width  = 2 * radius2;
          var B_height = 2 * radius2;
          var C_width  = 2 * radius3;
          var C_height = 2 * radius3;
    
        // the following needs Jquery
          var circle_a = $("#left_circle");
          var circle_b = $("#right_circle");
          var circle_c = $("#third_circle");
    
          circle_a.animate( {
                            'top'   : A_top + 'px',
                            'left'  : A_left + 'px',
                            'width' : A_width + 'px',
                            'height': A_height + 'px'
                            }, 500 );
    
          circle_b.animate( {
                            'top'   : B_top + 'px',
                            'left'  : B_left + 'px',
                            'width' : B_width + 'px',
                            'height': B_height + 'px'
                            }, 500 );
    
    
          circle_c.animate( {
                            'top'   : C_top + 'px',
                            'left'  : C_left + 'px',
                            'width' : C_width + 'px',
                            'height': C_height + 'px'
                            }, 500 );
    
    
        }
      }
      $("#circleOneInput").keyup(changeCircles);
      $("#circleTwoInput").keyup(changeCircles);
      $("#circleThreeInput").keyup(changeCircles);
    }); // end ready
     JS <<<    
    
    HTML>>
    长方体中的相切圆
    圈出一个
    圈出两个
    圈三 HTML> 身体 { 背景色:白色; } #主集装箱 { 背景色:#中交; 宽度:800px; 高度:800px; 保证金:自动; 边框:实心#中交1px; -o-边界半径:4px; -moz边界半径:4px; -webkit边界半径:4px; 边界半径:4px; } #内胆 { 宽度:100%; 身高:100%; 位置:相对位置; } 圆圈 { 位置:绝对位置; 文本对齐:居中; 字体家族:幻想; } #左环 { 顶部:0px; 左:0px; 宽度:300px; 高度:300px; } #右旋 { 顶部:0px; 左:0px; 宽度:300px; 高度:300px; } #第三圈 { 顶部:0px; 左:0px; 宽度:300px; 高度:300px; } #用户控件 { 填充:30px; 宽度:400px; 高度:200px; 保证金:自动; 边缘顶部:30px; 背景色:#dddddd; } #电路输入 { 边缘底部:10px; } #圆圈输入 { 边缘底部:10px; } #用户控件 { 位置:绝对位置; 左:20px; 顶部:50px; 宽度:200px; } CSS> $(函数(){ 函数转换圆(){ $(“#inputWarning”).remove(); var radius1=parseInt($(“#circleOneInput”).val(),10; var radius2=parseInt($(“#circleTwoInput”).val(),10); var radius3=parseInt($(“#circleThreeInput”).val(),10; log('radius1='+radius1+','+ '半径2='+半径2+','+ “半径3=”+半径3 ); if(isNaN(半径1)| | isNaN(半径2)| | isNaN(半径3)) { $(“#userControlsForm”)。在('请只输入数字')之后; } 其他的 { //规范化圆的大小 如果(半径1<10) { 半径1=10; } 如果(半径2<10) { 半径2=10; } 如果(半径3<10) { 半径3=10; } 如果(半径1>150) { 半径1=150; } 如果(半径2>150) { 半径2=150; } 如果(半径3>150) { 半径3=150; } //实际的圆是否发生变化 //1)计算 //2)制作动画 //计算三角形的边 var a=半径2+半径3; var b=半径1+半径3; var c=半径2+半径1; //获取包含div的维度 var container_width=$(“#内部_container”).width(); var container_height=$(“#内部_container”).height(); var center_x=容器宽度/2.0; 变量中心y=容器高度/2.0; //计算圆b内角度的余弦和正弦 var cos_β=((a*a)+(c*c)-(b*b))/(2*a*c); var sin_beta=Math.sqrt(1-cos_beta*cos_beta); //计算圆a和b的坐标 var-Ax=0; var Ay=0; var Bx=半径1+半径2;