//円と円の交点を求める。成功したときは必ず長さ2の配列(2点)、失敗したときは長さ0の配列を返す public PointXY[] CrossPoints(Circle b) { //b座標を原点として計算 float xx = x - b.x; float yy = y - b.y; float w = xx * xx + yy * yy; if (w < 0.00001F) { return(new PointXY[0]); } float a = (w + b.r * b.r - r * r) / 2.0F; float v = (float)Math.Sqrt(w * b.r * b.r - a * a); if (float.IsNaN(v)) { return(new PointXY[0]); } PointXY[] result = new PointXY[2]; result[0] = new PointXY( (a * xx + yy * v) / w + b.x, (a * yy - xx * v) / w + b.y ); result[1] = new PointXY( (a * xx - yy * v) / w + b.x, (a * yy + xx * v) / w + b.y ); return(result); }
// -180.0 < angle <= 180.0の値を返します // ベクトルbが反時計周りにあるとき、値は負の数を返します public float SignedAngle(PointXY b) { float rad = (float)Math.Acos(InnerProduct(b) / (Length() * b.Length())); if (OuterProduct(b) < 0.0F) { rad = -rad; } return(rad * 180.0F / (float)Math.PI); }
// 内積。クラスのベクトルとベクトルbのなす角が90で0、90を超えると負の数を返します public float InnerProduct(PointXY b) { return(x * b.x + y * b.y); }
// 0.0 <= angle <= 180.0の値を返します public float Angle(PointXY b) { float rad = (float)Math.Acos(InnerProduct(b) / (Length() * b.Length())); return(rad * 180.0F / (float)Math.PI); }
// 外積。ベクトルbがこのクラスのベクトルの時計回り側にあると返り値はプラスになります public float OuterProduct(PointXY b) { return(x * b.y - y * b.x); }