Last active
January 5, 2020 17:34
-
-
Save zawa-works/534fec44dd938ad9707264d1a984c6c5 to your computer and use it in GitHub Desktop.
円と円の交点を求めるプログラム
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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