私は三角形を持っていて、2 つの頂点の座標を知っています: A=(x1,y1),B=(x2,y2) すべての角度: ABC=90∘,CAB=30∘ および BCA=60∘ およびすべてのエッジ長さ。3 番目の頂点 C=(x3,y3) の座標を見つけるにはどうすればよいですか?
私は2つの解決策があることを知っています(私は両方が欲しいです)。
私は三角形を持っていて、2 つの頂点の座標を知っています: A=(x1,y1),B=(x2,y2) すべての角度: ABC=90∘,CAB=30∘ および BCA=60∘ およびすべてのエッジ長さ。3 番目の頂点 C=(x3,y3) の座標を見つけるにはどうすればよいですか?
私は2つの解決策があることを知っています(私は両方が欲しいです)。
あなたはポイントを得る:
x3 = x2 + s*(y1 - y2)
y3 = y2 + s*(x2 - x1)
と
x3 = x2 + s*(y2 - y1)
y3 = y2 + s*(x1 - x2)
どこs = 1/sqrt(3) ≈ 0.577350269
30-60-90 直角三角形では、最小の脚 (90 度の角度に隣接する最小の辺) の長さは斜辺 (90 度の角度の反対側) の 1/2 です。どの脚が線分 AB であるかを判断できます。
それから、角度がどこに行くのかを推測します。
次に、座標を計算するには、正しい角度で正しい半径の長さを持つ半径の円上の点を選択するだけです。
角度を時計回りまたは反時計回りに測定すると、エッジ AB が対称線である対称三角形が得られます。
角度は既に与えられているので、二次式を使用して AB の長さを計算します。
L(AB) = Sqrt[(x1-x2)^2 + (y1-y2)^2].
ここで、x = L(AC) = 2*L(BC) とすると、直角三角形なので、
L(AC)^2 = L(BC)^2 + L(AB)^2、
x^2 = (0.5x)^2 + L(AB)^2 なので、L(AB) = x*Sqrt[3]/2 となり、すでに L(AB) を計算しているため、x が得られます。
元の AB の角度は a = arctan([y2-y1]/[x2-x1]) です。これで、上または下に 30 度 (必要に応じて a+30 または a-30 を使用) を測定し、角度 a +/- で半径 x (上で計算した) の円 (A を中心とする) 上の点 C をマークできます。 30.
次に、Cは座標を持っています
x3 = x1 + x*cos(a+30)
y3 = y1 + x*sin(a+30)
または、(a-30) を使用して対称三角形を取得できます。
入力として 2 つの点と辺の数が指定された場合に、完全な多角形の点を返すコードを次に示します。これは Android(Java) 向けに記述されており、ロジックは他の言語でも再利用できます。
private static final float angleBetweenPoints(PointF a, PointF b) {
float deltaY = b.y - a.y;
float deltaX = b.x - a.x;
return (float) (Math.atan2(deltaY, deltaX));
}
private static PointF pullPointReferenceToLineWithAngle(PointF a, PointF b,
float angle) {
float angleBetween = angleBetweenPoints(b, a);
float distance = (float) Math.hypot(b.x - a.x, b.y - a.y);
float x = (float) (b.x + (distance * Math.cos((angleBetween + angle))));
float y = (float) (b.y + (distance * Math.sin((angleBetween + angle))));
return new PointF(x, y);
}
private static List<PointF> pullPolygonPointsFromBasePoints(PointF a,
PointF b, int noOfSides) {
List<PointF> points = new ArrayList<>();
points.add(a);
points.add(b);
if (noOfSides < 3) {
return points;
}
float angleBetweenTwoSides = (float) ((((noOfSides - 2) * 180) / noOfSides)
* Math.PI / 180);
for (int i = 3; i <= noOfSides; i++) {
PointF nextPoint = pullPointReferenceToLineWithAngle(
points.get(i - 3), points.get(i - 2), angleBetweenTwoSides);
points.add(nextPoint);
}
return points;
}
使い方は onDraw メソッドです:
PointF a = new PointF(100, 600);
PointF b = new PointF(300, 500);
int noOfSides = 3;
List<PointF> polygonPoints = pullPolygonPointsFromBasePoints(a, b,
noOfSides);
drawPolyPoints(canvas, noOfSides, polygonPoints);
これは直角三角形です。角度 ABC は 90 度なので、A と B を結ぶベクトルを計算し、これを AA と呼び、正規化します。
AA = (x2-x1,y2-y1) / |(x2-x1,y2-y1)|
に垂直な単位ベクトルAA
は、
BB = (-(y2-y1),x2-x1) / |(x2-x1,y2-y1)|
P1
AC は AB に垂直であるため、次のように最初のポイントを取得できます。
P1 = (x2,y2) + K * BB
ここで、K は辺 AC の長さに等しいスカラー値です (質問で既に知っていると言う)。2 番目のソリューション ポイントP2
は、負のBB
方向に進むことによって単純に与えられます。
P2 = (x2,y2) - K * BB