// // Perpendicular(Segment(A, B), Segment(C, D)), Angle(A, M, D), Angle(D, M, B) -> Congruent(Angle(A, M, D), Angle(D, M, B)) // // B // / // C-----------/-----------D // / M // / // A public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_IMPLY_CONGRUENT_ADJACENT_ANGLES; // The list of new grounded clauses if they are deduced List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is Angle) && !(c is Perpendicular)) { return(newGrounded); } if (c is Angle) { Angle newAngle = c as Angle; // Find two candidate lines cut by the same transversal foreach (Perpendicular perp in candPerpendicular) { foreach (Angle oldAngle in candAngles) { newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(perp, oldAngle, newAngle)); } } candAngles.Add(newAngle); } else if (c is Perpendicular) { Perpendicular newPerpendicular = c as Perpendicular; // Avoid generating if the situation is: // // | // | // |_ // |_|_________ // if (newPerpendicular.StandsOnEndpoint()) { return(newGrounded); } for (int i = 0; i < candAngles.Count - 1; i++) { for (int j = i + 1; j < candAngles.Count; j++) { newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(newPerpendicular, candAngles[i], candAngles[j])); } } candPerpendicular.Add(newPerpendicular); } return(newGrounded); }
// ) | B // ) | // O )| S // ) | // ) | // ) | A // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_TO_RADIUS_IS_TANGENT; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is CircleSegmentIntersection) { CircleSegmentIntersection newInter = clause as CircleSegmentIntersection; foreach (Perpendicular oldPerp in candidatePerpendicular) { newGrounded.AddRange(InstantiateTheorem(newInter, oldPerp, oldPerp)); } foreach (Strengthened oldStreng in candidateStrengthened) { newGrounded.AddRange(InstantiateTheorem(newInter, oldStreng.strengthened as Perpendicular, oldStreng)); } candidateIntersections.Add(newInter); } else if (clause is Perpendicular) { Perpendicular newPerp = clause as Perpendicular; foreach (CircleSegmentIntersection oldInter in candidateIntersections) { newGrounded.AddRange(InstantiateTheorem(oldInter, newPerp, newPerp)); } candidatePerpendicular.Add(newPerp); } else if (clause is Strengthened) { Strengthened newStreng = clause as Strengthened; if (!(newStreng.strengthened is Perpendicular)) { return(newGrounded); } foreach (CircleSegmentIntersection oldInter in candidateIntersections) { newGrounded.AddRange(InstantiateTheorem(oldInter, newStreng.strengthened as Perpendicular, newStreng)); } candidateStrengthened.Add(newStreng); } return(newGrounded); }
private static List <EdgeAggregator> InstantiateToAltitude(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Triangle) { Triangle tri = clause as Triangle; foreach (Perpendicular perp in candidatePerpendicular) { newGrounded.AddRange(InstantiateToAltitude(tri, perp, perp)); } foreach (Strengthened streng in candidateStrengthened) { newGrounded.AddRange(InstantiateToAltitude(tri, streng.strengthened as Perpendicular, streng)); } candidateTriangle.Add(tri); } else if (clause is Perpendicular) { Perpendicular perp = clause as Perpendicular; foreach (Triangle tri in candidateTriangle) { newGrounded.AddRange(InstantiateToAltitude(tri, perp, perp)); } candidatePerpendicular.Add(perp); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; // Only interested in strenghthened intersection -> perpendicular or -> perpendicular bisector if (!(streng.strengthened is Perpendicular)) { return(newGrounded); } foreach (Triangle tri in candidateTriangle) { newGrounded.AddRange(InstantiateToAltitude(tri, streng.strengthened as Perpendicular, streng)); } candidateStrengthened.Add(streng); } return(newGrounded); }
// // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),... // All angles will have measure 180^o // There will be nC3 resulting clauses. // public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { if (!(c is Intersection)) return null; Intersection pCand = (Intersection)c; List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (pCand.isPerpendicular == true) { Perpendicular newPerpendicular = new Perpendicular(pCand.lhs,pCand.rhs, NAME); List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(pCand); newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return newGrounded; }
private static List <EdgeAggregator> CheckAndGeneratePerpendicular(Perpendicular perp, Parallel parallel, Intersection inter, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // The perpendicular intersection must refer to one of the parallel segments Segment shared = perp.CommonSegment(parallel); if (shared == null) { return(newGrounded); } // The other intersection must refer to a segment in the parallel pair Segment otherShared = inter.CommonSegment(parallel); if (otherShared == null) { return(newGrounded); } // The two shared segments must be distinct if (shared.Equals(otherShared)) { return(newGrounded); } // Transversals must align if (!inter.OtherSegment(otherShared).Equals(perp.OtherSegment(shared))) { return(newGrounded); } // Strengthen the old intersection to be perpendicular Strengthened strengthenedPerp = new Strengthened(inter, new Perpendicular(inter)); // Construct hyperedge List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(parallel); antecedent.Add(inter); newGrounded.Add(new EdgeAggregator(antecedent, strengthenedPerp, annotation)); return(newGrounded); }
// // Perpendicular(M, Segment(A,B), Segment(C, D)), // Angle(A, B, D), Angle(C, B, D) -> Complementary(Angle(A, B, D), Angle(C, B, D)) // // A D // | / // | / // | / // | / // |/_____________________ C // B // public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.ADJACENT_ANGLES_PERPENDICULAR_IMPLY_COMPLEMENTARY; // The list of new grounded clauses if they are deduced List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is Angle) && !(c is Perpendicular)) { return(newGrounded); } if (c is Angle) { Angle newAngle = c as Angle; foreach (Perpendicular perp in candPerpendicular) { foreach (Angle oldAngle in candAngles) { newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(perp, oldAngle, newAngle)); } } candAngles.Add(newAngle); } else if (c is Perpendicular) { Perpendicular newPerpendicular = c as Perpendicular; for (int i = 0; i < candAngles.Count - 1; i++) { for (int j = i + 1; j < candAngles.Count; j++) { newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(newPerpendicular, candAngles[i], candAngles[j])); } } candPerpendicular.Add(newPerpendicular); } return(newGrounded); }
// // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),... // All angles will have measure 180^o // There will be nC3 resulting clauses. // public static List <KeyValuePair <List <GroundedClause>, GroundedClause> > Instantiate(GroundedClause c) { if (!(c is Intersection)) { return(null); } Intersection pCand = (Intersection)c; List <KeyValuePair <List <GroundedClause>, GroundedClause> > newGrounded = new List <KeyValuePair <List <GroundedClause>, GroundedClause> >(); if (pCand.isPerpendicular == true) { Perpendicular newPerpendicular = new Perpendicular(pCand.lhs, pCand.rhs, NAME); List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(pCand); newGrounded.Add(new KeyValuePair <List <GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return(newGrounded); }
/// <summary> /// Алгорит распознавания круговых движений /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MouseBox_MouseMove(object sender, MouseEventArgs e) { // Отображаем координаты позиции курсора мыши labelCoord.Text = e.Location.ToString(); // Проверяем можем ли мы рисовать if (isPaintEntry && e.Button == MouseButtons.Left) { // Добавляем позицию мыши в список точек path.Add(e.Location); // Отрисовка траектории движения курсора мыши if (isDrawTrajectory && path.Count > 2) { g.DrawLines(blPen, path.ToArray()); } // Проводим вычисления с заданной точночтью аппроксимации if (path.Count % step == 0) { /// /// Инициализация /// // Аппроксимация сегмента AB траекториии движения курсора мыши PointF A = path[path.Count - (int)step]; PointF B = path[path.Count - 1]; // Средняя точка R сегмента AB траектории движения курсора мыши PointF R = path[path.Count - ((int)step / 2)]; // Точка M - середина отрезка AB PointF M = new PointF((A.X + B.X) / 2f, (A.Y + B.Y) / 2f); // Прямая AB Straight straightAB = new Straight(A.X, A.Y, B.X, B.Y); // Перпендикуляр к прямой AB в точке M Perpendicular perpendicularMK = new Perpendicular(M.X, M.Y, straightAB.K); // Перпендикуляр к прмяой MK в точке R Perpendicular perpendicularRO = new Perpendicular(R.X, R.Y, perpendicularMK.K); // Точка пересечения MK и RO PointF O = GetIntersectionPoint(perpendicularMK.K, perpendicularMK.B, perpendicularRO.K, perpendicularRO.B); // Если точки совпадают пропускаем итерацию if (O.X == M.X) { return; } // Точка для определения коэффициента для нахождения точки радиуса PointF K1 = new PointF(M.X + ((O.X < M.X) ? (-5f) : (+5f)), perpendicularMK.getY(M.X + ((O.X < M.X) ? (-5f) : (+5f)))); // Вычисляем длину отрезка MK1 float lengthMK1 = (float)Math.Sqrt(((K1.X - M.X) * (K1.X - M.X)) + ((K1.Y - M.Y) * (K1.Y - M.Y))); // Вычисляем отношение длин MK к MK1 float k = radiusСurvature / lengthMK1; // Вычисляем координаты точки K PointF K = new PointF( M.X - ((K1.X - M.X) * k), perpendicularMK.getY(M.X - ((K1.X - M.X) * k)) ); // Определяем допустимые координаты x для перпендикуляра PointF startPointMK = new PointF(); startPointMK.X = Math.Min(K.X, M.X); startPointMK.Y = perpendicularMK.getY(startPointMK.X); PointF endPointMK = new PointF(); endPointMK.X = Math.Max(K.X, M.X); endPointMK.Y = perpendicularMK.getY(endPointMK.X); if (!oldStartpointMK.IsEmpty && !oldStartpointMK.IsEmpty && IntersectionSegments(startPointMK, endPointMK, oldStartpointMK, oldEndPointMK)) { status = true; this.OnMoveMouseCircularPath(EventArgs.Empty); } else { status = false; this.OnMoveMouseCircularPath(EventArgs.Empty); } oldStartpointMK = startPointMK; oldEndPointMK = endPointMK; /// /// Отрисовка /// // Отрисовываем отрезок AB if (isDrawAB) { g.DrawLine(rPen, A, B); } // Отрисовка прямой MK if (isDrawPMK) { g.DrawLine(dsgPen, new PointF(0f, perpendicularMK.getY(0f)), new PointF(300f, perpendicularMK.getY(300f)) ); } // Отрисовываем отрезок MK if (isDrawSMK) { g.DrawLine(gPen, startPointMK, endPointMK); } // Отрисовываем перпендикуляр RO if (isDrawPRO) { g.DrawLine(bPen, new PointF(0f, perpendicularRO.getY(0f)), new PointF(300f, perpendicularRO.getY(300f)) ); } // Отсрисовка точек M & R if (isDrawPointA) { g.FillEllipse(rBrush, A.X - ((float)sizePoint / 2f), A.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } if (isDrawPointB) { g.FillEllipse(rBrush, B.X - ((float)sizePoint / 2f), B.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } if (isDrawPointM) { g.FillEllipse(rBrush, M.X - ((float)sizePoint / 2f), M.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } if (isDrawPointR) { g.FillEllipse(bBrush, R.X - ((float)sizePoint / 2f), R.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } if (isDrawPointO) { g.FillEllipse(gBrush, O.X - ((float)sizePoint / 2f), O.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } if (isDrawPointK) { g.FillEllipse(gBrush, K.X - ((float)sizePoint / 2f), K.Y - ((float)sizePoint / 2f), sizePoint, sizePoint); } } } }
// // Perpendicular(Segment(E, F), Segment(C, D)), // Parallel(Segment(E, F), Segment(A, B)), // Intersection(M, Segment(A, B), Segment(C, D)) -> Perpendicular(Segment(A, B), Segment(C, D)) // // E B // | | // C----|-------|--------D // | N | M // | | // F A // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.TRANSVERSAL_PERPENDICULAR_TO_PARALLEL_IMPLY_BOTH_PERPENDICULAR; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Parallel) { Parallel newParallel = clause as Parallel; foreach (Perpendicular perp in candidatePerpendicular) { foreach (Intersection inter in candidateIntersection) { newGrounded.AddRange(CheckAndGeneratePerpendicular(perp, newParallel, inter, perp)); } } foreach (Strengthened streng in candidateStrengthened) { foreach (Intersection inter in candidateIntersection) { newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, newParallel, inter, streng)); } } candidateParallel.Add(newParallel); } else if (clause is Perpendicular) { Perpendicular newPerp = clause as Perpendicular; foreach (Parallel parallel in candidateParallel) { foreach (Intersection inter in candidateIntersection) { newGrounded.AddRange(CheckAndGeneratePerpendicular(newPerp, parallel, inter, newPerp)); } } candidatePerpendicular.Add(newPerp); } else if (clause is Intersection) { Intersection newIntersection = clause as Intersection; foreach (Parallel parallel in candidateParallel) { foreach (Perpendicular perp in candidatePerpendicular) { newGrounded.AddRange(CheckAndGeneratePerpendicular(perp, parallel, newIntersection, perp)); } } foreach (Parallel parallel in candidateParallel) { foreach (Strengthened streng in candidateStrengthened) { newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, parallel, newIntersection, streng)); } } candidateIntersection.Add(newIntersection); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Perpendicular)) { return(newGrounded); } foreach (Parallel parallel in candidateParallel) { foreach (Intersection inter in candidateIntersection) { if (!inter.Equals(streng.original)) { newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, parallel, inter, streng)); } } } candidateStrengthened.Add(streng); } return(newGrounded); }
// // Perpendicular(B, Segment(A, B), Segment(B, C)) -> RightAngle(), RightAngle() // private static List <EdgeAggregator> InstantiateFromPerpendicular(GroundedClause original, Perpendicular perp) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); // top // | // |_ // |_|____ right if (perp.StandsOnEndpoint()) { Point top = perp.lhs.OtherPoint(perp.intersect); Point right = perp.rhs.OtherPoint(perp.intersect); Strengthened streng = new Strengthened(new Angle(top, perp.intersect, right), new RightAngle(top, perp.intersect, right)); newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation)); } // top // | // |_ // left ____|_|____ right else if (perp.StandsOn()) { Point top = perp.lhs.Point1; Point center = perp.intersect; Point left = perp.rhs.Point1; Point right = perp.rhs.Point2; if (perp.lhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect)) { left = perp.lhs.Point1; right = perp.lhs.Point2; top = perp.rhs.OtherPoint(perp.intersect); } else if (perp.rhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect)) { left = perp.rhs.Point1; right = perp.rhs.Point2; top = perp.lhs.OtherPoint(perp.intersect); } else { return(newGrounded); } Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right)); Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left)); newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation)); } // top // | // |_ // left ____|_|____ right // | // | // bottom else if (perp.Crossing()) { Point top = perp.lhs.Point1; Point bottom = perp.lhs.Point2; Point center = perp.intersect; Point left = perp.rhs.Point1; Point right = perp.rhs.Point2; Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right)); Strengthened bottomRight = new Strengthened(new Angle(right, center, bottom), new RightAngle(right, center, bottom)); Strengthened bottomLeft = new Strengthened(new Angle(left, center, bottom), new RightAngle(left, center, bottom)); Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left)); newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, bottomRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, bottomLeft, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation)); } else { return(newGrounded); } return(newGrounded); }
// public static List <KeyValuePair <List <GroundedClause>, GroundedClause> > Instantiate(GroundedClause c) { //Exit if c is neither a parallel set nor an intersection if (!(c is Parallel) && !(c is Intersection)) { return(new List <KeyValuePair <List <GroundedClause>, GroundedClause> >()); } List <Intersection> foundCand = new List <Intersection>(); //Variable holding intersections that will used for theorem // The list of new grounded clauses if they are deduced List <KeyValuePair <List <GroundedClause>, GroundedClause> > newGrounded = new List <KeyValuePair <List <GroundedClause>, GroundedClause> >(); if (c is Parallel) { Parallel newParallel = (Parallel)c; candParallel.Add((Parallel)c); //Create a list of all segments in the intersection list by individual segment and list of intersecting segments var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); //Iterate through all segments intersected by each key segment foreach (var group in query1) { if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2)) { //If a segment that intersected both parallel lines was found, find the intersection objects. var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList <GroundedClause>(newParallel); //Add parallel set to antecedents } } } else if (c is Intersection) { candIntersection.Add((Intersection)c); Intersection newintersect = (Intersection)c; var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); foreach (Parallel p in candParallel) { foreach (var group in query1) { if (group.Contains(p.segment1) && group.Contains(p.segment2)) { //list intersections involving intersecting segement and two paralell segments var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList <GroundedClause>(p); } } } } //TODO: Make sure there will only be one set of intersections found at a time if (foundCand.Count() > 1) { antecedent.AddRange((IEnumerable <GroundedClause>)(foundCand)); //Add the two intersections to antecedent int index; index = (foundCand[0].isPerpendicular == false) ? 0 : 1; foundCand[index].setPerpendicular(true); Perpendicular newPerpendicular = new Perpendicular(foundCand[index].lhs, foundCand[index].rhs, NAME); //Add the new perpendicular set newGrounded.Add(new KeyValuePair <List <GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return(newGrounded); }
private static List <EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!Utilities.CompareValues(angle1.measure + angle2.measure, 90)) { return(newGrounded); } // The perpendicular intersection must occur at the same vertex of both angles (we only need check one). if (!(angle1.GetVertex().Equals(perp.intersect) && angle2.GetVertex().Equals(perp.intersect))) { return(newGrounded); } // Are the angles adjacent? Segment sharedRay = angle1.IsAdjacentTo(angle2); if (sharedRay == null) { return(newGrounded); } // Do the non-shared rays for both angles align with the segments defined by the perpendicular intersection? if (!perp.DefinesBothRays(angle1.OtherRayEquates(sharedRay), angle2.OtherRayEquates(sharedRay))) { return(newGrounded); } // // Now we have perpendicular -> complementary angles scenario // Complementary cas = new Complementary(angle1, angle2); // Construct hyperedge List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(perp); antecedent.Add(angle1); antecedent.Add(angle2); newGrounded.Add(new EdgeAggregator(antecedent, cas, annotation)); return(newGrounded); }
private static List <EdgeAggregator> InstantiateToAltitude(Triangle triangle, Perpendicular perp, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // Acquire the side of the triangle containing the intersection point // This point may or may not be directly on the triangle side Segment baseSegment = triangle.GetSegmentWithPointOnOrExtends(perp.intersect); if (baseSegment == null) { return(newGrounded); } // The altitude must pass through the intersection point as well as the opposing vertex Point oppositeVertex = triangle.OtherPoint(baseSegment); Segment altitude = new Segment(perp.intersect, oppositeVertex); // The alitude must alig with the intersection if (!perp.ImpliesRay(altitude)) { return(newGrounded); } // The opposing side must align with the intersection if (!perp.OtherSegment(altitude).IsCollinearWith(baseSegment)) { return(newGrounded); } // // Create the new Altitude object // Altitude newAltitude = new Altitude(triangle, altitude); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(triangle); antecedent.Add(original); newGrounded.Add(new EdgeAggregator(antecedent, newAltitude, annotation)); // // Check if this induces a second altitude for a right triangle (although we don't know this is a strengthened triangle) // The intersection must be on the vertex of the triangle if (triangle.HasPoint(perp.intersect)) { Angle possRightAngle = new Angle(triangle.OtherPoint(new Segment(perp.intersect, oppositeVertex)), perp.intersect, oppositeVertex); if (triangle.HasAngle(possRightAngle)) { Altitude secondAltitude = new Altitude(triangle, new Segment(perp.intersect, oppositeVertex)); newGrounded.Add(new EdgeAggregator(antecedent, secondAltitude, annotation)); } } return(newGrounded); }
private static List <EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!Utilities.CompareValues(angle1.measure, angle2.measure)) { return(newGrounded); } // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection. if (!(perp.InducesNonStraightAngle(angle1) && perp.InducesNonStraightAngle(angle1))) { return(newGrounded); } // // Now we have perpendicular -> congruent angles scenario // GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle1, angle2); // Construct hyperedge List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(perp); antecedent.Add(angle1); antecedent.Add(angle2); newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation)); return(newGrounded); }
// ) | B // ) | // O )| S // ) | // ) | // ) | A // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S)) // private static List <EdgeAggregator> InstantiateTheorem(CircleSegmentIntersection inter, Perpendicular perp, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // The intersection points must be the same. if (!inter.intersect.StructurallyEquals(perp.intersect)) { return(newGrounded); } // Get the radius - if it exists Segment radius = null; Segment garbage = null; inter.GetRadii(out radius, out garbage); if (radius == null) { return(newGrounded); } // Two intersections, not a tangent situation. if (garbage != null) { return(newGrounded); } // The radius can't be the same as the Circ-Inter segment. if (inter.segment.HasSubSegment(radius)) { return(newGrounded); } // Does this perpendicular apply to this Arc intersection? if (!perp.HasSegment(radius) || !perp.HasSegment(inter.segment)) { return(newGrounded); } Strengthened newTangent = new Strengthened(inter, new Tangent(inter)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); newGrounded.Add(new EdgeAggregator(antecedent, newTangent, annotation)); return(newGrounded); }
public void Do(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> IntelItems, TimeSpan canonicalTime, Profiler profiler) { if (canonicalTime == TimeSpan.Zero) { return; } if (MiningSystem.Recalling > 0 || currentPosition > 120) { Recalling = true; } if (Recalling && state < 3) { state = 3; } if (state == 1) // Diving to surface of asteroid { MineTask.Do(IntelItems, canonicalTime, profiler); MineTask.Destination.MaxSpeed = Autopilot.GetMaxSpeedFromBrakingDistance(kFarSensorDist); if (MineTask.Status == TaskStatus.Complete || !MiningSystem.SensorsFarClear()) { EntryPoint = Autopilot.Reference.WorldMatrix.Translation + MineTask.Destination.Direction * (kFarSensorDist - 10); MineTask.Destination.MaxSpeed = 1f; state = 2; } } else if (state == 2) // Boring tunnel { bool sampleHome = false; double distToMiningEnd = (Autopilot.Reference.WorldMatrix.Translation - MiningEnd).Length(); if (MiningSystem.SensorsClear()) { MineTask.Destination.Position = MiningEnd; } else if (MiningSystem.SensorsBack()) { MineTask.Destination.Position = EntryPoint; } else { MineTask.Destination.Position = Vector3D.Zero; if (SampleCount <= 0) { SampleCount = kSampleFrequency; var cargoPercentage = MonitorSubsystem.GetPercentage(MonitorOptions.Cargo); if (LastSampleCargoPercentages.Count >= kMaxSampleCount) { LastSampleCargoPercentages.Enqueue(cargoPercentage); var sampleGreater = 0; var sampleLesser = 0; var comparePercentage = LastSampleCargoPercentages.Dequeue() + 0.00001; foreach (var percentage in LastSampleCargoPercentages) { if (percentage > comparePercentage) { sampleGreater++; } else { sampleLesser++; } } if (sampleGreater > sampleLesser) { if (!HitOre) { HitOre = true; var currentCoords = GetMiningPosition(currentPosition); miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 1; } if (LowestExpectedOreDist == -1) { LowestExpectedOreDist = (float)distToMiningEnd - 5; } } else { if (HitOre || distToMiningEnd < LowestExpectedOreDist) { sampleHome = true; if (!HitOre) { var currentCoords = GetMiningPosition(currentPosition); miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 2; } } } } else { LastSampleCargoPercentages.Enqueue(cargoPercentage); } } else { SampleCount--; } } MiningSystem.Drill(); MineTask.Do(IntelItems, canonicalTime, profiler); if (GoHomeCheck() || MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome) { if (MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome) { UpdateMiningMatrix(currentPosition); IncrementCurrentPosition(); HitOre = false; } state = 3; MineTask.Destination.MaxSpeed = 2; LastSampleCargoPercentages.Clear(); } } else if (state == 3) // Exiting tunnel { MiningSystem.StopDrill(); if (MineTask.Destination.Position != ExitPoint) { MineTask.Destination.Position = EntryPoint; } MineTask.Do(IntelItems, canonicalTime, profiler); if (MineTask.Status == TaskStatus.Complete) { if (MineTask.Destination.Position == EntryPoint) { MineTask.Destination.Position = ExitPoint; MineTask.Destination.MaxSpeed = 100; } else { state = 10; } } } else if (state == 10) // Resuming to approach point { if (GoHomeCheck() || Recalling) { state = 4; } else { LeadTask.Destination.Position = ApproachPoint; LeadTask.Do(IntelItems, canonicalTime, profiler); if (LeadTask.Status == TaskStatus.Complete) { var position = GetMiningPosition(currentPosition); LeadTask.Destination.Position = ApproachPoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist); LeadTask.Destination.MaxSpeed = 10; ExitPoint = LeadTask.Destination.Position; state = 11; } } } else if (state == 11) // Search for the digging spot { if (GoHomeCheck() || Recalling) { state = 4; } else { LeadTask.Do(IntelItems, canonicalTime, profiler); if (LeadTask.Status == TaskStatus.Complete) { state = 1; MiningSystem.SensorsOn(); var position = GetMiningPosition(currentPosition); MineTask.Destination.Position = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) - MineTask.Destination.Direction * MiningSystem.CloseDist; MiningEnd = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) + MineTask.Destination.Direction * MiningDepth; } } } else if (state == 4) // Going home { if (DockingSubsystem == null || DockingSubsystem.HomeID == -1 || DockTaskGenerator == null || UndockTaskGenerator == null) { state = 9999; } else { if (HomeTask == null) { HomeTask = DockTaskGenerator.GenerateMoveToAndDockTask(MyTuple.Create(IntelItemType.NONE, (long)0), IntelItems, 40); } HomeTask.Do(IntelItems, canonicalTime, profiler); if (HomeTask.Status != TaskStatus.Incomplete) { HomeTask = null; homeCheck = false; state = 5; } } } else if (state == 5) // Waiting for refuel/unload { if (Recalling) { state = 9999; } if ((Program.Me.WorldMatrix.Translation - EntryPoint).LengthSquared() > MiningSystem.CancelDist * MiningSystem.CancelDist) { state = 9999; } if (LeaveHomeCheck()) { state = 6; } } else if (state == 6) // Undocking { if (DockingSubsystem != null && DockingSubsystem.Connector.Status == MyShipConnectorStatus.Connected) { if (UndockTask == null) { UndockTask = UndockTaskGenerator.GenerateUndockTask(canonicalTime); } } if (UndockTask != null) { UndockTask.Do(IntelItems, canonicalTime, profiler); if (UndockTask.Status != TaskStatus.Incomplete) { UndockTask = null; state = 10; } } else { state = 10; } } else if (state == 9999) { Status = TaskStatus.Complete; } }
// A // |) // | ) // | ) // Q------- O---X---) D // | ) // | ) // |) // C // // Perpendicular(Segment(Q, D), Segment(A, C)) -> Congruent(Arc(A, D), Arc(D, C)) -> Congruent(Segment(AX), Segment(XC)) // private static List <EdgeAggregator> InstantiateTheorem(Intersection inter, CircleSegmentIntersection arcInter, Perpendicular perp, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // // Does this intersection apply to this perpendicular? // if (!inter.intersect.StructurallyEquals(perp.intersect)) { return(newGrounded); } // Is this too restrictive? if (!((inter.HasSegment(perp.lhs) && inter.HasSegment(perp.rhs)) && (perp.HasSegment(inter.lhs) && perp.HasSegment(inter.rhs)))) { return(newGrounded); } // // Does this perpendicular intersection apply to a given circle? // // Acquire the circles for which the segments are secants. List <Circle> secantCircles1 = Circle.GetSecantCircles(perp.lhs); List <Circle> secantCircles2 = Circle.GetSecantCircles(perp.rhs); List <Circle> intersection = Utilities.Intersection <Circle>(secantCircles1, secantCircles2); if (!intersection.Any()) { return(newGrounded); } // // Find the single, unique circle that has as chords the components of the perpendicular intersection // Circle theCircle = null; Segment chord1 = null; Segment chord2 = null; foreach (Circle circle in intersection) { chord1 = circle.GetChord(perp.lhs); chord2 = circle.GetChord(perp.rhs); if (chord1 != null && chord2 != null) { theCircle = circle; break; } } Segment diameter = chord1.Length > chord2.Length ? chord1 : chord2; Segment chord = chord1.Length < chord2.Length ? chord1 : chord2; // // Does the arc intersection apply? // if (!arcInter.HasSegment(diameter)) { return(newGrounded); } if (!theCircle.StructurallyEquals(arcInter.theCircle)) { return(newGrounded); } // // Create the bisector // Strengthened sb = new Strengthened(inter, new SegmentBisector(inter, diameter)); Strengthened ab = new Strengthened(arcInter, new ArcSegmentBisector(arcInter)); // For hypergraph List <GroundedClause> antecedentArc = new List <GroundedClause>(); antecedentArc.Add(arcInter); antecedentArc.Add(original); antecedentArc.Add(theCircle); newGrounded.Add(new EdgeAggregator(antecedentArc, ab, annotation)); List <GroundedClause> antecedentSegment = new List <GroundedClause>(); antecedentSegment.Add(inter); antecedentSegment.Add(original); antecedentSegment.Add(theCircle); newGrounded.Add(new EdgeAggregator(antecedentSegment, sb, annotation)); return(newGrounded); }
// public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { //Exit if c is neither a parallel set nor an intersection if (!(c is Parallel) && !(c is Intersection)) return new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); List<Intersection> foundCand = new List<Intersection>(); //Variable holding intersections that will used for theorem // The list of new grounded clauses if they are deduced List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (c is Parallel) { Parallel newParallel = (Parallel)c; candParallel.Add((Parallel)c); //Create a list of all segments in the intersection list by individual segment and list of intersecting segments var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); //Iterate through all segments intersected by each key segment foreach (var group in query1) { if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2)) { //If a segment that intersected both parallel lines was found, find the intersection objects. var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList<GroundedClause>(newParallel); //Add parallel set to antecedents } } } else if (c is Intersection) { candIntersection.Add((Intersection)c); Intersection newintersect = (Intersection)c; var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); foreach (Parallel p in candParallel) { foreach (var group in query1) { if (group.Contains(p.segment1) && group.Contains(p.segment2)) { //list intersections involving intersecting segement and two paralell segments var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList<GroundedClause>(p); } } } } //TODO: Make sure there will only be one set of intersections found at a time if (foundCand.Count() > 1) { antecedent.AddRange((IEnumerable<GroundedClause>)(foundCand)); //Add the two intersections to antecedent int index; index = (foundCand[0].isPerpendicular == false) ? 0 : 1; foundCand[index].setPerpendicular(true); Perpendicular newPerpendicular = new Perpendicular(foundCand[index].lhs,foundCand[index].rhs, NAME); //Add the new perpendicular set newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return newGrounded; }