I've been trying to rotate a square for a project, I've done research and think I have the right formula to calculate the rotated points. I calculate the points as if they're individual around the center of the square. How to fix it?
//Declaring variables
float x0, y0, xo, yo,x1,y1,x2,y2,x3,y3, theta, newx, newy, s, c;
void setup() {
size (800,800);
//To debug
//frameRate(1);
fill(0);
//Initializing variables
xo = 400;
yo = 400;
x0 = 350;
y0 = 450;
x1 = 350;
y1 = 350;
x2 = 450;
y2 = 350;
x3 = 450;
y3 = 450;
theta = radians(5);
s = sin(theta);
c = cos(theta);
}
void draw() {
//Reseting the background
background(255);
//Drawing the square
quad(x0,y0,x1,y1,x2,y2,x3,y3);
//Doing the rotations
x0 = rotateX(x0,y0);
y0 = rotateY(x0,y0);
x1 = rotateX(x1,y1);
y1 = rotateY(x1,y1);
x2 = rotateX(x2,y2);
y2 = rotateY(x2,y2);
x3 = rotateX(x3,y3);
y3 = rotateY(x3,y3);
}
//Rotate x coordinate method
float rotateX(float x, float y) {
x -= xo;
newx = x * c - y * s;
x = newx + xo;
return x;
}
//Rotate y coordinate method
float rotateY(float x, float y) {
y -= yo;
newy = x * s - y * c;
y = newy + yo;
return y;
}
There are two things:
1) You have a sign error in rotateY(). The y term should have a positive sign:
newy = x * s + y * c;
2) When you do this:
x0 = rotateX(x0,y0);
y0 = rotateY(x0,y0);
... then the first call modifies x0, which the second call then uses. But the second call needs the original coordinates to rotate correctly:
float x0Rotated = rotateX(x0, y0);
y0 = rotateY(x0, y0);
x0 = x0Rotated;
The same thing for the other points.
Related
I made a program that creates parallel lines from the mouse coordinates with a certain distance away which can be modified by the distance variable at the beginning of the code. The problem is that it does not work as it should when drawing.
Line 1 and Line 2 are the lines that are parallel to the line formed from the mouse coordinates, the "pointSlope" variable.
distance = 30
function setup() {
createCanvas(600, 600);
}
function draw() {
lineCreate([pmouseX,pmouseY], [mouseX,mouseY])
}
function lineCreate(point1, point2) {
fill(0)
stroke(0)
x0 = point1[0];
x1 = point2[0];
y0 = point1[1];
y1 = point2[1];
if (abs(x1 - x0) > abs(y1 - y0)) {
if (x0 > x1) {
let t = x0; x0 = x1; x1 = t;
t = y0; y0 = y1; y1 = t;
}
for (let x = x0; x <= x1; x++) {
let slope = (y1-y0) * (x-x0) / (x1-x0)
let y = y0 + (y1-y0) * (x-x0) / (x1-x0);
line1 = y + distance*Math.sqrt(1+pow(slope,2))
line2 = y - distance*Math.sqrt(1+pow(slope,2))
circle(x, line1, 2, 2);
circle(x, line2, 2, 2);
}
} else {
if (y0 > y1) {
let t = x0; x0 = x1; x1 = t;
t = y0; y0 = y1; y1 = t;
}
for (let y = y0; y <= y1; y++) {
let x = x0 + (x1-x0) * (y-y0) / (y1-y0);
circle(x, y, 2, 2);
}
}
}
I think that using vectors may help you in this situation, try this code as example:
let dist = 40;
function setup() {
createCanvas(600, 600);
v = createVector();
noStroke();
}
function draw() {
lineCreate();
}
function lineCreate() {
v.x = mouseX-pmouseX; v.y = mouseY-pmouseY;
h = v.heading();
LX = dist*cos(h+PI/2); LY = dist*sin(h+PI/2);
RX = dist*cos(h-PI/2); RY = dist*sin(h-PI/2);
for (let i=0; i<v.mag(); i++) {
fill(0).circle(pmouseX+i*cos(h),pmouseY+i*sin(h),2);
fill(160).circle(pmouseX+LX+i*cos(h),pmouseY+LY+i*sin(h),2);
fill(160).circle(pmouseX+RX+i*cos(h),pmouseY+RY+i*sin(h),2);
}
}
Here we are drawing two parallel lines in road-like path, but as you can see there are gaps in turns caused by using pmouse. I think, that it will not be possible to get rid of these artifacts, if you not move away from using the pmouse to more complex ways of calculating the trajectory.
I just started to learn processing and I have a few problems that I couldn't solve. I hope someone could help me. This should draw lines where i could choose the starting and finishing points with mousePressed(), but I failed before trying implementing that.
//int x1, x2, y1, y2;
void setup() {
size(640, 480);
}
void draw() {
midpoint(0, 0, 100, 100);
}
//void mousePressed() {
// pmouseX =x1;
// pmouseY =y1;
// mouseX =x2;
// mouseY =y2;
//}
void midpoint(int x1, int y1, int x2, int y2) {
int dx, dy, d, x, y;
dx = x2-x1;
dy = y2-y1;
d = 2*dy-dx;
x = x1;
y = y1;
for (int i = 1; i <dx; i++) {
point(x, y);
if (d>0) {
y++;
d+=2*(dy-dx);
} else {
d+=2*dy;
}
x++;
}
}
My problem is that it will not always draw the line.
e.g.
midpoint(0,0,100,100);
it will draw it
midpoint(100,100,0,0);
it draws nothing.
It should draw the same line if I exchange the points coordinates, or draw a single point if the coordinates are the same.
In Bresenham's midpoint line algorithm you have to be careful with the gradient of the line drawn, the base algorithm you described only works for gradients between 0 and 1. In order to deal with gradients that are steeper (m > 1 or m < -1), you have to switch the roles of the x and y values, therefore you have to step in y and then calculate x. Also to deal with negative steps just switch the point order.
void midpoint(int x1, int y1, int x2, int y2) {
// Is gradient of line greater than 1
boolean steep = abs(y2-y1) > abs(x2-x1);
int temp;
if (steep) { // If gradient > 1
// Swap roles of x and y components to step in y instead
temp = y1;
y1 = x1;
x1 = temp;
temp = y2;
y2 = x2;
x2 = temp;
}
if (x2 < x1) {
// Swap points such that step in x is positive
temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}
// Change in x and y which are now both positive
int dx = x2 - x1;
int dy = abs(y2 - y1);
// Step in y
int sy = y2 > y1 ? 1 : -1;
int y = y1;
// Decision variable
int d = 2*dy-dx;
// Small step in x
for (int x=x1; x<=x2; x++) {
// Depending on gradient plot x and y
if (steep) {
point(y, x);
} else {
point(x, y);
}
// Update decision parameter
if (d>0) {
y += sy;
d+=2*(dy-dx);
}else{
d+=2*dy;
}
}
}
I need to make the mousePressed() function act as a source of gravity and impact the rest of the double pendulum.
Ideally it will "push" the pendulum circles like wind with strength depending on distance. I have included the code i have so far for the double pendulum, it includes a tracer that follows the end of the pendulum with a line, the gravity function will allow the user to create their own lines with some form of control.
float r1 = 200;
float r2 = 200;
float m1 = 40;
float m2 = 40;
float a1 = PI/2;
float a2 = PI/2;
float a1_v = 0;
float a2_v = 0;
float g = 1;
float px2 = -1;
float py2 = -1;
float cx, cy;
PGraphics canvas;
void setup() {
size(1024, 768);
cx = width/2;
cy = 200;
canvas = createGraphics(width, height);
canvas.beginDraw();
canvas.background(255);
canvas.endDraw();
}
void draw() {
background(255);
imageMode(CORNER);
image(canvas, 0, 0, width, height);
float num1 = -g * (2 * m1 + m2) * sin(a1);
float num2 = -m2 * g * sin(a1-2*a2);
float num3 = -2*sin(a1-a2)*m2;
float num4 = a2_v*a2_v*r2+a1_v*a1_v*r1*cos(a1-a2);
float den = r1 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a1_a = (num1 + num2 + num3*num4) / den;
num1 = 2 * sin(a1-a2);
num2 = (a1_v*a1_v*r1*(m1+m2));
num3 = g * (m1 + m2) * cos(a1);
num4 = a2_v*a2_v*r2*m2*cos(a1-a2);
den = r2 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a2_a = (num1*(num2+num3+num4)) / den;
translate(cx, cy);
stroke(0);
strokeWeight(2);
float x1 = r1 * sin(a1);
float y1 = r1 * cos(a1);
float x2 = 0;
float y2 = 0;
if(mousePressed){
x2 = mouseX - cx;
y2 = mouseY - cy;
}else{
x2 = x1 + r2 * sin(a2);
y2 = y1 + r2 * cos(a2);
}
line(0, 0, x1, y1);
fill(0);
ellipse(x1, y1, m1, m1);
line(x1, y1, x2, y2);
fill(0);
ellipse(x2, y2, m2, m2);
a1_v += a1_a;
a2_v += a2_a;
a1 += a1_v;
a2 += a2_v;
// a1_v *= 0.99;
// a2_v *= 0.99;
canvas.beginDraw();
//canvas.background(0, 1);
canvas.translate(cx, cy);
canvas.stroke(0);
if (frameCount > 1) {
canvas.line(px2, py2, x2, y2);
}
canvas.endDraw();
px2 = x2;
py2 = y2;
}
If it was the dist to a point it would be
dist(mouseX, mouseY, x, y)
for
point(x,y)
but how can I calculate dist() from the mouse's current position to
rectMode(CORNERS);
rect(x1,y2,x2,y2);
Thanks
Something like this should do it:
float distrect(float x, float y, float x1, float y1, float x2, float y2){
float dx1 = x - x1;
float dx2 = x - x2;
float dy1 = y - y1;
float dy2 = y - y2;
if (dx1*dx2 < 0) { // x is between x1 and x2
if (dy1*dy2 < 0) { // (x,y) is inside the rectangle
return min(min(abs(dx1), abs(dx2)),min(abs(dy1),abs(dy2)));
}
return min(abs(dy1),abs(dy2));
}
if (dy1*dy2 < 0) { // y is between y1 and y2
// we don't have to test for being inside the rectangle, it's already tested.
return min(abs(dx1),abs(dx2));
}
return min(min(dist(x,y,x1,y1),dist(x,y,x2,y2)),min(dist(x,y,x1,y2),dist(x,y,x2,y1)));
}
Basically, you need to figure out if the closes point is on one of the sides, or in the corner. This picture may help, it shows the distance of a point from a rectangle for different positions of the point:
Here's a somewhat interactive program which accomplishes what you're looking for. You can drop it into Processing and run it if you would like.
EDIT: Here's a screenshot:
// Declare vars.
int x_click = -20; // Initializes circle and point off-screen (drawn when draw executes)
int y_click = -20;
float temp = 0.0;
float min_dist = 0.0;
int x1, x2, x3, x4, y1, y2, y3, y4;
// Setup loop.
void setup() {
size(400, 400);
// Calculate the points of a 40x40 centered rectangle
x1 = width/2 - 20;
y1 = height/2 - 20;
x2 = width/2 + 20;
y2 = y1;
x3 = x1;
y3 = height/2 + 20;
x4 = x2;
y4 = y3;
}
// Draw loop.
void draw(){
background(255);
// Draws a purple rectangle in the center of the screen.
rectMode(CENTER);
fill(154, 102, 200);
rect(width/2, height/2, 40, 40);
// Draws an orange circle where the user last clicked.
ellipseMode(CENTER);
fill(204, 102, 0);
ellipse(x_click, y_click, 10, 10);
// Draws black point where the user last clicked.
fill(0);
point(x_click, y_click);
// Draws min dist onscreen.
textAlign(CENTER);
fill(0);
text("min dist = " + min_dist, width/2, height/2 + 150);
}
void mousePressed(){
x_click = mouseX;
y_click = mouseY;
// If the click isn't perpendicular to any side of the rectangle, the min dist is a corner.
if ( ((x_click <= x1) || (x_click >= x2)) && ((y_click <= y1) || (y_click >= y3)) ) {
min_dist = min(min(dist(x1,y1,x_click,y_click),dist(x2,y2,x_click,y_click)), min(dist(x3,y3,x_click,y_click),dist(x4,y4,x_click,y_click)));
} else if( (x_click > x1) && (x_click < x2) && ((y_click < y1) || (y_click > y3)) ) {
// outside of box, closer to top or bottom
min_dist = min(abs(y_click - y1), abs(y_click - y3));
} else if( (y_click > y1) && (y_click < y3) && ((x_click < x1) || (x_click > x2)) ) {
// outside of box, closer to right left
min_dist = min(abs(x_click - x1), abs(x_click - x2));
} else {
// inside of box, check against all boundaries
min_dist = min(min(abs(y_click - y1), abs(y_click - y3)),min(abs(x_click - x1), abs(x_click - x2)));
}
// Print to console for debugging.
//println("minimum distance = " + min_dist);
}
This is what I use. If you are only interested in the relative distance there is probably no need to take the square root which should make it slightly quicker.
- (NSInteger) distanceFromRect: (CGPoint) aPoint rect: (CGRect) aRect
{
NSInteger posX = aPoint.x;
NSInteger posY = aPoint.y;
NSInteger leftEdge = aRect.origin.x;
NSInteger rightEdge = aRect.origin.x + aRect.size.width;
NSInteger topEdge = aRect.origin.y;
NSInteger bottomEdge = aRect.origin.y + aRect.size.height;
NSInteger deltaX = 0;
NSInteger deltaY = 0;
if (posX < leftEdge) deltaX = leftEdge - posX;
else if (posX > rightEdge) deltaX = posX - rightEdge;
if (posY < topEdge) deltaY = topEdge - posY;
else if (posY > bottomEdge) deltaY = posY - bottomEdge;
NSInteger distance = sqrt(deltaX * deltaX + deltaY * deltaY);
return distance;
}
How do I calculate the intersection points of two circles. I would expect there to be either two, one or no intersection points in all cases.
I have the x and y coordinates of the centre-point, and the radius for each circle.
An answer in python would be preferred, but any working algorithm would be acceptable.
Intersection of two circles
Written by Paul Bourke
The following note describes how to find the intersection point(s)
between two circles on a plane, the following notation is used. The
aim is to find the two points P3 = (x3,
y3) if they exist.
First calculate the distance d between the center
of the circles. d = ||P1 - P0||.
If d > r0 + r1 then there are no solutions,
the circles are separate. If d < |r0 -
r1| then there are no solutions because one circle is
contained within the other. If d = 0 and r0 =
r1 then the circles are coincident and there are an
infinite number of solutions.
Considering the two triangles P0P2P3
and P1P2P3 we can write
a2 + h2 = r02 and
b2 + h2 = r12
Using d = a + b we can solve for a, a =
(r02 - r12 +
d2 ) / (2 d)
It can be readily shown that this reduces to
r0 when the two circles touch at one point, ie: d =
r0 + r1
Solve for h by substituting a into the first
equation, h2 = r02 - a2
So P2 = P0 + a ( P1 -
P0 ) / d And finally, P3 =
(x3,y3) in terms of P0 =
(x0,y0), P1 =
(x1,y1) and P2 =
(x2,y2), is x3 =
x2 +- h ( y1 - y0 ) / d
y3 = y2 -+ h ( x1 - x0 ) /
d
Source: http://paulbourke.net/geometry/circlesphere/
Here is my C++ implementation based on Paul Bourke's article. It only works if there are two intersections, otherwise it probably returns NaN NAN NAN NAN.
class Point{
public:
float x, y;
Point(float px, float py) {
x = px;
y = py;
}
Point sub(Point p2) {
return Point(x - p2.x, y - p2.y);
}
Point add(Point p2) {
return Point(x + p2.x, y + p2.y);
}
float distance(Point p2) {
return sqrt((x - p2.x)*(x - p2.x) + (y - p2.y)*(y - p2.y));
}
Point normal() {
float length = sqrt(x*x + y*y);
return Point(x/length, y/length);
}
Point scale(float s) {
return Point(x*s, y*s);
}
};
class Circle {
public:
float x, y, r, left;
Circle(float cx, float cy, float cr) {
x = cx;
y = cy;
r = cr;
left = x - r;
}
pair<Point, Point> intersections(Circle c) {
Point P0(x, y);
Point P1(c.x, c.y);
float d, a, h;
d = P0.distance(P1);
a = (r*r - c.r*c.r + d*d)/(2*d);
h = sqrt(r*r - a*a);
Point P2 = P1.sub(P0).scale(a/d).add(P0);
float x3, y3, x4, y4;
x3 = P2.x + h*(P1.y - P0.y)/d;
y3 = P2.y - h*(P1.x - P0.x)/d;
x4 = P2.x - h*(P1.y - P0.y)/d;
y4 = P2.y + h*(P1.x - P0.x)/d;
return pair<Point, Point>(Point(x3, y3), Point(x4, y4));
}
};
Why not just use 7 lines of your favorite procedural language (or programmable calculator!) as below.
Assuming you are given P0 coords (x0,y0), P1 coords (x1,y1), r0 and r1 and you want to find P3 coords (x3,y3):
d=sqr((x1-x0)^2 + (y1-y0)^2)
a=(r0^2-r1^2+d^2)/(2*d)
h=sqr(r0^2-a^2)
x2=x0+a*(x1-x0)/d
y2=y0+a*(y1-y0)/d
x3=x2+h*(y1-y0)/d // also x3=x2-h*(y1-y0)/d
y3=y2-h*(x1-x0)/d // also y3=y2+h*(x1-x0)/d
Here's an implementation in Javascript using vectors. The code is well documented, you should be able to follow it. Here's the original source
See live demo here:
// Let EPS (epsilon) be a small value
var EPS = 0.0000001;
// Let a point be a pair: (x, y)
function Point(x, y) {
this.x = x;
this.y = y;
}
// Define a circle centered at (x,y) with radius r
function Circle(x,y,r) {
this.x = x;
this.y = y;
this.r = r;
}
// Due to double rounding precision the value passed into the Math.acos
// function may be outside its domain of [-1, +1] which would return
// the value NaN which we do not want.
function acossafe(x) {
if (x >= +1.0) return 0;
if (x <= -1.0) return Math.PI;
return Math.acos(x);
}
// Rotates a point about a fixed point at some angle 'a'
function rotatePoint(fp, pt, a) {
var x = pt.x - fp.x;
var y = pt.y - fp.y;
var xRot = x * Math.cos(a) + y * Math.sin(a);
var yRot = y * Math.cos(a) - x * Math.sin(a);
return new Point(fp.x+xRot,fp.y+yRot);
}
// Given two circles this method finds the intersection
// point(s) of the two circles (if any exists)
function circleCircleIntersectionPoints(c1, c2) {
var r, R, d, dx, dy, cx, cy, Cx, Cy;
if (c1.r < c2.r) {
r = c1.r; R = c2.r;
cx = c1.x; cy = c1.y;
Cx = c2.x; Cy = c2.y;
} else {
r = c2.r; R = c1.r;
Cx = c1.x; Cy = c1.y;
cx = c2.x; cy = c2.y;
}
// Compute the vector <dx, dy>
dx = cx - Cx;
dy = cy - Cy;
// Find the distance between two points.
d = Math.sqrt( dx*dx + dy*dy );
// There are an infinite number of solutions
// Seems appropriate to also return null
if (d < EPS && Math.abs(R-r) < EPS) return [];
// No intersection (circles centered at the
// same place with different size)
else if (d < EPS) return [];
var x = (dx / d) * R + Cx;
var y = (dy / d) * R + Cy;
var P = new Point(x, y);
// Single intersection (kissing circles)
if (Math.abs((R+r)-d) < EPS || Math.abs(R-(r+d)) < EPS) return [P];
// No intersection. Either the small circle contained within
// big circle or circles are simply disjoint.
if ( (d+r) < R || (R+r < d) ) return [];
var C = new Point(Cx, Cy);
var angle = acossafe((r*r-d*d-R*R)/(-2.0*d*R));
var pt1 = rotatePoint(C, P, +angle);
var pt2 = rotatePoint(C, P, -angle);
return [pt1, pt2];
}
Try this;
def ri(cr1,cr2,cp1,cp2):
int1=[]
int2=[]
ori=0
if cp1[0]<cp2[0] and cp1[1]!=cp2[1]:
p1=cp1
p2=cp2
r1=cr1
r2=cr2
if cp1[1]<cp2[1]:
ori+=1
elif cp1[1]>cp2[1]:
ori+=2
elif cp1[0]>cp2[0] and cp1[1]!=cp2[1]:
p1=cp2
p2=cp1
r1=cr2
r2=cr1
if p1[1]<p2[1]:
ori+=1
elif p1[1]>p2[1]:
ori+=2
elif cp1[0]==cp2[0]:
ori+=4
if cp1[1]>cp2[1]:
p1=cp1
p2=cp2
r1=cr1
r2=cr2
elif cp1[1]<cp2[1]:
p1=cp2
p2=cp1
r1=cr2
r2=cr1
elif cp1[1]==cp2[1]:
ori+=3
if cp1[0]>cp2[0]:
p1=cp2
p2=cp1
r1=cr2
r2=cr1
elif cp1[0]<cp2[0]:
p1=cp1
p2=cp2
r1=cr1
r2=cr2
if ori==1:#+
D=calc_dist(p1,p2)
tr=r1+r2
el=tr-D
a=r1-el
b=r2-el
A=a+(el/2)
B=b+(el/2)
thta=math.degrees(math.acos(A/r1))
rs=p2[1]-p1[1]
rn=p2[0]-p1[0]
gd=rs/rn
yint=p1[1]-((gd)*p1[0])
dty=calc_dist(p1,[0,yint])
aa=p1[1]-yint
bb=math.degrees(math.asin(aa/dty))
d=90-bb
e=180-d-thta
g=(dty/math.sin(math.radians(e)))*math.sin(math.radians(thta))
f=(g/math.sin(math.radians(thta)))*math.sin(math.radians(d))
oty=yint+g
h=f+r1
i=90-e
j=180-90-i
l=math.sin(math.radians(i))*h
k=math.cos(math.radians(i))*h
iy2=oty-l
ix2=k
int2.append(ix2)
int2.append(iy2)
m=90+bb
n=180-m-thta
p=(dty/math.sin(math.radians(n)))*math.sin(math.radians(m))
o=(p/math.sin(math.radians(m)))*math.sin(math.radians(thta))
q=p+r1
r=90-n
s=math.sin(math.radians(r))*q
t=math.cos(math.radians(r))*q
otty=yint-o
iy1=otty+s
ix1=t
int1.append(ix1)
int1.append(iy1)
elif ori==2:#-
D=calc_dist(p1,p2)
tr=r1+r2
el=tr-D
a=r1-el
b=r2-el
A=a+(el/2)
B=b+(el/2)
thta=math.degrees(math.acos(A/r1))
rs=p2[1]-p1[1]
rn=p2[0]-p1[0]
gd=rs/rn
yint=p1[1]-((gd)*p1[0])
dty=calc_dist(p1,[0,yint])
aa=yint-p1[1]
bb=math.degrees(math.asin(aa/dty))
c=180-90-bb
d=180-c-thta
e=180-90-d
f=math.tan(math.radians(e))*p1[0]
g=math.sqrt(p1[0]**2+f**2)
h=g+r1
i=180-90-e
j=math.sin(math.radians(e))*h
jj=math.cos(math.radians(i))*h
k=math.cos(math.radians(e))*h
kk=math.sin(math.radians(i))*h
l=90-bb
m=90-e
tt=l+m+thta
n=(dty/math.sin(math.radians(m)))*math.sin(math.radians(thta))
nn=(g/math.sin(math.radians(l)))*math.sin(math.radians(thta))
oty=yint-n
iy1=oty+j
ix1=k
int1.append(ix1)
int1.append(iy1)
o=bb+90
p=180-o-thta
q=90-p
r=180-90-q
s=(dty/math.sin(math.radians(p)))*math.sin(math.radians(o))
t=(s/math.sin(math.radians(o)))*math.sin(math.radians(thta))
u=s+r1
v=math.sin(math.radians(r))*u
vv=math.cos(math.radians(q))*u
w=math.cos(math.radians(r))*u
ww=math.sin(math.radians(q))*u
ix2=v
otty=yint+t
iy2=otty-w
int2.append(ix2)
int2.append(iy2)
elif ori==3:#y
D=calc_dist(p1,p2)
tr=r1+r2
el=tr-D
a=r1-el
b=r2-el
A=a+(el/2)
B=b+(el/2)
b=math.sqrt(r1**2-A**2)
int1.append(p1[0]+A)
int1.append(p1[1]+b)
int2.append(p1[0]+A)
int2.append(p1[1]-b)
elif ori==4:#x
D=calc_dist(p1,p2)
tr=r1+r2
el=tr-D
a=r1-el
b=r2-el
A=a+(el/2)
B=b+(el/2)
b=math.sqrt(r1**2-A**2)
int1.append(p1[0]+b)
int1.append(p1[1]-A)
int2.append(p1[0]-b)
int2.append(p1[1]-A)
return [int1,int2]
def calc_dist(p1,p2):
return math.sqrt((p2[0] - p1[0]) ** 2 +
(p2[1] - p1[1]) ** 2)