/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using VisionCommon; using System; using System.Collections.Generic; namespace VisionAligner { /// /// 헤드 얼라인 /// public class AlignModeHead : AlignMode { private AlignModeHead() : base() { // For UnitTest } /// /// 생성자 /// /// 얼라인 정보 public AlignModeHead(AlignInfo alignInfo) : base(alignInfo) { } #region N-Point Align /// /// N-포인트 얼라인 보정량 T를 계산한다. /// /// 패턴 검출 위치 /// 레퍼런스(기준) 위치 /// 좌표계의 Y축 반전 여부 /// 얼라인 보정량 protected override AlignDelta CalculateT( List meaPoints, List refPoints, int flipY) { // Align Direction : refPoints -> meaPoints // meaPoints, refPoints 순서가 반대 return AlignerImpl.CalculateT(refPoints, meaPoints, flipY); } /// /// ICP 알고리즘을 이용하여 N-포인트 얼라인 보정량 T를 계산한다. /// /// 패턴 검출 위치 /// 레퍼런스(기준) 위치 /// 좌표계의 Y축 반전 여부 /// 얼라인 보정량 protected override AlignDelta CalculateT_ICP( List meaPoints, List refPoints, int flipY) { // Align Direction : refPoints -> meaPoints // meaPoints, refPoints 순서가 반대 return AlignerImpl.CalculateT_ICP(refPoints, meaPoints, flipY); } /// /// N-포인트 얼라인 보정량 XY를 계산한다. /// /// 패턴 검출 위치 /// 레퍼런스(기준) 위치 /// 좌표계의 Y축 반전 여부 /// 회전 원점 /// 얼라인 보정량 T /// 얼라인 보정량 protected override AlignDelta CalculateXY( List meaPoints, List refPoints, int flipY, DoublePoint thetaOrigin, Angle alignT) { var normalizedAngle = CoordSystem.NormalizeAngleDirection(alignT, flipY); // XY var centroidRefPoint = DoublePoint.GetCentroid(refPoints); var markOffsets = new List(); for (int i = 0; i < refPoints.Count; i++) { markOffsets.Add(meaPoints[i] - refPoints[i]); } var centroidMarkOffset = DoublePoint.GetCentroid(markOffsets); AlignDelta alignDeltaXY = NativeAligner.HeadAlignXY( normalizedAngle, centroidRefPoint - thetaOrigin, // Coordinate Origin Convert : (0, 0) -> thetaOrigin centroidMarkOffset - thetaOrigin); // Coordinate Origin Convert : (0, 0) -> thetaOrigin alignDeltaXY.Translation += thetaOrigin; // Coordinate Origin Convert : (0, 0) <- thetaOrigin return new AlignDelta( alignDeltaXY.Translation, Angle.CreateWithDegree(0)); } #endregion #region 1-Point Align /// /// 1-포인트 얼라인 보정량 XYT를 계산한다. /// /// 패턴 검출 위치 /// 레퍼런스(기준) 위치 /// 좌표계의 Y축 반전 여부 /// 회전 원점 /// 얼라인 보정량 T /// 얼라인 보정량 protected override AlignDelta CalculateXYT( DoublePoint meaPoint, DoublePoint refPoint, int flipY, DoublePoint thetaOrigin, Angle theta) { // Align Direction : refPoint -> meaPoint // refPoint, meaPoint 순서가 반대이다. // theta는 패턴의 검출 각도 = 자재의 틀어짐 // -> Head 보정량 : theta 부호 반전 불필요 return AlignerImpl.CalculateXYT(refPoint, meaPoint, theta, thetaOrigin, flipY); } #endregion } }