Skip to content

Instantly share code, notes, and snippets.

@zawa-works
Last active January 5, 2020 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zawa-works/534fec44dd938ad9707264d1a984c6c5 to your computer and use it in GitHub Desktop.
Save zawa-works/534fec44dd938ad9707264d1a984c6c5 to your computer and use it in GitHub Desktop.
円と円の交点を求めるプログラム
float x1, y1, r1;
float x2, y2, r2;
void setup() {
size(640, 360);
x1 = width/2;
y1 = height/2;
r1 = 100;
r2 = 110;
stroke(#542E54);
noCursor();
}
void draw() {
background(#A6BED7);
strokeWeight(5);
noFill();
//円1
ellipse(x1, y1, 2*r1, 2*r1);
//円2
ellipse(x2, y2, 2*r2, 2*r2);
//交点
strokeWeight(3);
fill(#7FFF5C);
drawCrossPoints();
}
void mouseMoved() {
x2 = mouseX;
y2 = mouseY;
}
void keyPressed() {
switch(keyCode) {
case UP:
if (r2 < 200)r2+=10;
break;
case DOWN:
if (r2 > 110)r2-=10;
break;
default:
break;
}
}
void drawCrossPoints() {
PVector[]crossPoints = getCirclesCrossPoints(x1, y1, r1, x2, y2, r2);
if (crossPoints == null)return;
for (PVector point : crossPoints)
ellipse(point.x, point.y, 15, 15);
}
//円と円の交点を取得する関数
PVector[] getCirclesCrossPoints(float x1, float y1, float r1, float x2, float y2, float r2) {
float a = 2*(x2 - x1);
float b = 2*(y2 - y1);
float c = sq(x1)-sq(x2)+sq(y1)-sq(y2)+sq(r2)-sq(r1);
return getLineCircleCrossPoints(a, b, c, x1, y1, r1);
}
//直線(ax + by + c = 0)と円(中心座標(circleX, circleY), 半径 r)の交点を取得する関数
PVector[] getLineCircleCrossPoints(float a, float b, float c, float circleX, float circleY, float r) {
//円の中心から直線までの距離
//mag(a, b) = √a^2+b^2
float d = abs((a*circleX+b*circleY+c)/mag(a, b));
//直線の垂線とX軸と平行な線がなす角度θ
float theta = atan2(b, a);
if (d > r) {
return null;
} else if (d == r) {
PVector[] point = new PVector[1];
//場合わけ
if (a*circleX+b*circleY+c > 0)theta += PI;
float crossX = r*cos(theta)+circleX;
float crossY = r*sin(theta)+circleY;
point[0] = new PVector(crossX, crossY);
return point;
} else {
PVector[] crossPoint = new PVector[2];
float[]crossX = new float[2];
float[]crossY = new float[2];
//alphaとbetaの角度を求める
float alpha, beta, phi;
phi = acos(d/r);
alpha = theta - phi;
beta = theta + phi;
//場合わけ
if (a*circleX+b*circleY+c > 0) {
alpha += PI;
beta += PI;
}
//交点の座標を求める
crossX[0] = r*cos(alpha) + circleX;
crossY[0] = r*sin(alpha) + circleY;
crossX[1] = r*cos(beta) + circleX;
crossY[1] = r*sin(beta) + circleY;
for (int i = 0; i < crossPoint.length; i++)
crossPoint[i] = new PVector(crossX[i], crossY[i]);
return crossPoint;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment