첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ 타원과 직선 교차점 배열 찾기 예제

------------------------------------------------------------------------------------------------------------------------

using System.Windows;

 

Point[] intersectionPointArray = FindEllipseLineIntersectionPointArray

(

    new Rect(100, 100, 200, 200), // 타원

    new Point(50, 50),            // 직선 시작점

    new Point(250, 250),          // 직선 종료점

    false

);

------------------------------------------------------------------------------------------------------------------------

 

■ 타원과 직선 교차점 배열 찾기

------------------------------------------------------------------------------------------------------------------------

using System;

using System.Collections.Generic;

using System.Windows;

 

#region 타원과 직선 교차점 배열 찾기 - FindEllipseLineIntersectionPointArray(rectangle, lineStartPoint, lineEndPoint, segmentOnly)

 

/// <summary>

/// 타원과 직선 교차점 배열 찾기

/// </summary>

/// <param name="rectangle">사각형</param>

/// <param name="lineStartPoint">직선 시작점</param>

/// <param name="lineEndPoint">직선 종료점</param>

/// <param name="segmentOnly">세그먼트만 여부</param>

/// <returns>타원과 직선 교차점 배열</returns>

public Point[] FindEllipseLineIntersectionPointArray(Rect rectangle, Point lineStartPoint, Point lineEndPoint, bool segmentOnly)

{

    if((rectangle.Width == 0) || (rectangle.Height == 0) || ((lineStartPoint.X == lineEndPoint.X) && (lineStartPoint.Y == lineEndPoint.Y)))

    {

        return new Point[] { };

    }

 

    if(rectangle.Width < 0)

    {

        rectangle.X     =  rectangle.Right;

        rectangle.Width = -rectangle.Width;

    }

            

    if(rectangle.Height < 0)

    {

        rectangle.Y      =  rectangle.Bottom;

        rectangle.Height = -rectangle.Height;

    }

 

    double centerX = rectangle.Left + rectangle.Width  / 2f;

    double centerY = rectangle.Top  + rectangle.Height / 2f;

 

    rectangle.X -= centerX;

    rectangle.Y -= centerY;

 

    lineStartPoint.X -= centerX;

    lineStartPoint.Y -= centerY;

 

    lineEndPoint.X -= centerX;

    lineEndPoint.Y -= centerY;

 

    double a = rectangle.Width  / 2;

    double b = rectangle.Height / 2;

 

    double c1 = (lineEndPoint.X - lineStartPoint.X) * (lineEndPoint.X - lineStartPoint.X) / a / a +

                (lineEndPoint.Y - lineStartPoint.Y) * (lineEndPoint.Y - lineStartPoint.Y) / b / b;

    double c2 = 2 * lineStartPoint.X * (lineEndPoint.X - lineStartPoint.X) / a / a +

                2 * lineStartPoint.Y * (lineEndPoint.Y - lineStartPoint.Y) / b / b;

    double c3 = lineStartPoint.X * lineStartPoint.X / a / a + lineStartPoint.Y * lineStartPoint.Y / b / b - 1;

 

    List<double> valueList = new List<double>();

 

    double discriminant = c2 * c2 - 4 * c1 * c3;

 

    if(discriminant == 0)

    {

        valueList.Add(-c2 / 2 / c1);

    }

    else if(discriminant > 0)

    {

        valueList.Add((double)((-c2 + Math.Sqrt(discriminant)) / 2 / c1));

        valueList.Add((double)((-c2 - Math.Sqrt(discriminant)) / 2 / c1));

    }

 

    List<Point> pointList = new List<Point>();

 

    foreach(double value in valueList)

    {

        if(!segmentOnly || ((value >= 0f) && (value <= 1f)))

        {

            double x = lineStartPoint.X + (lineEndPoint.X - lineStartPoint.X) * value + centerX;

            double y = lineStartPoint.Y + (lineEndPoint.Y - lineStartPoint.Y) * value + centerY;

 

            pointList.Add(new Point(x, y));

        }

    }

 

    return pointList.ToArray();

}

 

#endregion

------------------------------------------------------------------------------------------------------------------------

728x90
반응형
Posted by 사용자 icodebroker
TAG , , ,

댓글을 달아 주세요