Geometry 基于半径计算三个接触圆的位置
这最终是一个几何问题。我正在使用raphaeljs为一系列数据中的每个项目绘制3个面积圆。每个圆圈表示类别中的项目数 <>我希望圆圈接触,但不重叠,我希望整组集中在其母div的中间。 图表如下:Geometry 基于半径计算三个接触圆的位置,geometry,raphael,Geometry,Raphael,这最终是一个几何问题。我正在使用raphaeljs为一系列数据中的每个项目绘制3个面积圆。每个圆圈表示类别中的项目数 我希望圆圈接触,但不重叠,我希望整组集中在其母div的中间。 图表如下: 如果只知道每个圆的半径以及父div的宽度和高度,我将如何计算每个圆中心的xy坐标?我想得越多,我想我实际上是在试图画一个三角形,其中每个角都是圆的x,y中心。除了最初的问题之外,你还需要限制或选择一些约束条件。在您的示例图像中,您是如何决定旋转由中心形成的三角形的?三角形的“中心”叫什么 一种方法可能是:
如果只知道每个圆的半径以及父div的宽度和高度,我将如何计算每个圆中心的xy坐标?我想得越多,我想我实际上是在试图画一个三角形,其中每个角都是圆的x,y中心。除了最初的问题之外,你还需要限制或选择一些约束条件。在您的示例图像中,您是如何决定旋转由中心形成的三角形的?三角形的“中心”叫什么 一种方法可能是: 假设第一个圆位于原点(0,0) 假设第二个圆位于该点正上方(0,r1+r2) 计算第三点-这是两个圆的交点。一个以原点为中心,半径为r1+r3,另一个以(0,r1+r2)为中心,半径为r2+r3 现在你有了这三个点,你可以计算一个“中心” 然后你可以根据这个中心和你的div的尺寸画圆。这就是问题所在。您可以使用链接找到解决方案 我已经做过这个的迭代推广。给定两条彼此相切的曲线A和B,变换第三条曲线C,使其与其他两条曲线相切。用户以在两条固定曲线上选择点的形式提供一些提示。算法如下所示:
我很快会添加一个说明,但我目前无法访问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;