private void lineCrossTestToolStripMenuItem_Click(object sender, EventArgs e) { Vec v1 = new Vec(new Point2D(75F, 53F), new Point2D(96F, 80F)); Vec v2 = new Vec(new Point2D(250F, 50F), new Point2D(214F, 74F)); Point2D cross = Geom.LineCross(v1, v2); Console.WriteLine("X: " + cross.X.ToString() + ", Y:" + cross.Y.ToString()); }
/// <summary> /// Трилатеральный перенос точки исходного треугольника в целевой треугольник /// </summary> /// <param name="sourceTri">Исходный треугольник</param> /// <param name="destTri">Целевой треугольник</param> /// <param name="n">Исходная точка</param> /// <returns>Точка внутри целевого треугольника</returns> public static Point2D TrilateralXform(Triangle sourceTri, Triangle destTri, Point2D n) { Triangle tri; // // Вектора сторон // Vec ab = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(sourceTri.b.X, sourceTri.b.Y)); Vec ac = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(sourceTri.c.X, sourceTri.c.Y)); Vec bc = new Vec(new Point2D(sourceTri.b.X, sourceTri.b.Y), new Point2D(sourceTri.c.X, sourceTri.c.Y)); Vec ab2 = new Vec(new Point2D(destTri.a.X, destTri.a.Y), new Point2D(destTri.b.X, destTri.b.Y)); Vec ac2 = new Vec(new Point2D(destTri.a.X, destTri.a.Y), new Point2D(destTri.c.X, destTri.c.Y)); Vec bc2 = new Vec(new Point2D(destTri.b.X, destTri.b.Y), new Point2D(destTri.c.X, destTri.c.Y)); // // Проверка когда точка лежит на одной из сторон // if (Geom.DistanceFromPointToLine(n, ab) < 1F) { Vec vn = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(n.X, n.Y)); float scale = vn.Length() / ab.Length(); return(Geom.VecScale(ab2, scale).end); } if (Geom.DistanceFromPointToLine(n, ac) < 1F) { Vec vn = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(n.X, n.Y)); float scale = vn.Length() / ac.Length(); return(Geom.VecScale(ac2, scale).end); } if (Geom.DistanceFromPointToLine(n, bc) < 1F) { Vec vn = new Vec(new Point2D(sourceTri.b.X, sourceTri.b.Y), new Point2D(n.X, n.Y)); float scale = vn.Length() / bc.Length(); return(Geom.VecScale(bc2, scale).end); } // // Получение "срединных" точек // Vec cn = new Vec(new Point2D(sourceTri.c.X, sourceTri.c.Y), new Point2D(n.X, n.Y)); Point2D mpAB = Geom.LineCross(ab, cn); Vec bn = new Vec(new Point2D(sourceTri.b.X, sourceTri.b.Y), new Point2D(n.X, n.Y)); Point2D mpAC = Geom.LineCross(ac, bn); Vec an = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(n.X, n.Y)); Point2D mpBC = Geom.LineCross(bc, an); // // Получение соотношения отрезков разделяемых срединными точками // Vec a_mpAB = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(mpAB.X, mpAB.Y)); Vec mpAB_b = new Vec(new Point2D(mpAB.X, mpAB.Y), new Point2D(sourceTri.b.X, sourceTri.b.Y)); float sAB = a_mpAB.Length() / ab.Length(); Vec a_mpAC = new Vec(new Point2D(sourceTri.a.X, sourceTri.a.Y), new Point2D(mpAC.X, mpAC.Y)); Vec mpAC_c = new Vec(new Point2D(mpAC.X, mpAC.Y), new Point2D(sourceTri.c.X, sourceTri.c.Y)); float sAC = a_mpAC.Length() / ac.Length(); Vec b_mpBC = new Vec(new Point2D(sourceTri.b.X, sourceTri.b.Y), new Point2D(mpBC.X, mpBC.Y)); Vec mpBC_c = new Vec(new Point2D(mpBC.X, mpBC.Y), new Point2D(sourceTri.c.X, sourceTri.c.Y)); float sBC = b_mpBC.Length() / bc.Length(); // // Перенос срединных точек // Vec ab2_s = Geom.VecScale(ab2, sAB); Vec ac2_s = Geom.VecScale(ac2, sAC); Vec bc2_s = Geom.VecScale(bc2, sBC); // // Получение вершин внутреннего треугольника // Vec mpAB2_c2 = new Vec(new Point2D(ab2_s.end.X, ab2_s.end.Y), new Point2D(destTri.c.X, destTri.c.Y)); Vec mpAC2_b2 = new Vec(new Point2D(ac2_s.end.X, ac2_s.end.Y), new Point2D(destTri.b.X, destTri.b.Y)); Vec mpBC2_a2 = new Vec(new Point2D(bc2_s.end.X, bc2_s.end.Y), new Point2D(destTri.a.X, destTri.a.Y)); tri = new Triangle(); tri.a = Geom.LineCross(mpAB2_c2, mpAC2_b2); tri.b = Geom.LineCross(mpBC2_a2, mpAC2_b2); tri.c = Geom.LineCross(mpAB2_c2, mpBC2_a2); // // Вычисление барицентра // return(Geom.BaryCenter(tri)); }