Python - Python 두 점 사이의 거리 구하기
Python
- Python 기본
- Python 숫자 계산하기
- Python 변수 만들기
- Python 출력 방법
- Python 불과 비교, 논리 연산자
- Python 문자열 사용하기
- Python 리스트와 튜플 사용하기
- Python 시퀀스 자료형 활용하기
- Python 딕셔너리 사용하기
- Python if 조건문으로 특정 조건일 때 코드 실행하기
- Python else를 사용하여 두 방향으로 분기하기
- Python elif를 사용하여 두 방향으로 분기하기
- Python for 반복문
- Python while 반복문
- Python break, continue로 반복문 제어하기
- Python 중첩루프
- Python FizzBuzz 문제
- Python 터틀 그래픽스로 그림 그리기
- Python 리스트와 튜플 응용하기
- Python 리스트와 튜플 응용하기 - 2
- Python 2차원 리스트 사용하기
- Python 문자열 응용하기
- Python 딕셔너리 응용하기
- Python 세트 사용하기
- Python 파일 사용하기
- Python 회문 판별과 N-gram 만들기
- Python 함수 사용하기
- Python 함수에서 위치 인수와 키워드 인수 사용하기
- Python 함수에서 재귀호출 사용하기
- Python 람다 표현식 사용하기
- Python 클로저 사용하기
- Python 클래스 사용하기
- Python 클래스 속성과 정적, 클래스 메서드 사용하기
- Python 클래스 상속 사용하기
- Python 두 점 사이의 거리 구하기
- Python 예외 처리 사용하기
- Python 이터레이터 사용하기
- Python 제너레이터 사용하기
- Python 코루틴 사용하기
- Python 데코레이터 사용하기
- Python 정규표현식 사용하기
- Python 모듈과 패키지 사용하기
- Python 모듈과 패키지 만들기
두 점 사이의 거리 구하기
클래스를 활용하여 2차원 평면에서 위치를 표현한 뒤 두 점 사이의 거리를 구해보자.
1. 두 점 사이의 거리 구하기
두 점 사이의 거리를 구하기 전에 먼저 클래스로 점을 구현해보자.
클래스로 점 구현하기
2차원 평면에서 위치를 표현하려면 x와 y값이 필요하다. 다음과 같이 Point2D 클래스를 구현하고 x와 y를 속성으로 넣었다.
class Point2D:
def __init__(self, x, y):
self.x = x
self.y = y
이제 Point2D 클래스로 점 두 개를 만든다.
class Point2D:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Point2D(x=30, y=20) # 점1
p2 = Point2D(x=60, y=50) # 점2
print('p1: {} {}'.format(p1.x, p1.y)) # 30 20
print('p2: {} {}'.format(p2.x, p2.y)) # 60 50
#실행 결과
p1: 30 20
p2: 60 50
피타고라스의 정리로 두 점의 거리 구하기
여기서 두 점의 거리를 구하려면 어떻게 해야 할까요? 학교에서 배운 피타고라스의 정리를 이용하면 된다.
- 임의의 직각삼각형에서 빗변을 한 변으로 하는 정사각형의 넓이는 다른 두 변을 각각 한 변으로 하는 정사각형의 넓이의 합과 같다.
- a2(제곱) + b2(제곱) = c2(제곱)
피타고라스의 정리에 대입하려면 먼저 선 a와 b의 길이를 구해야 한다. 우리는 Point2D 클래스의 인스턴스에 두 점의 좌표 정보가 들어있으므로 인스턴스(변수)를 활용하면 된다
a = p2.x - p1.x # 선 a의 길이
b = p2.y - p1.y # 선 b의 길이
a는 p2의 x에서 p1의 x를 빼면 되고, b는 p2의 y에서 p1의 y를 빼면 된다.
그다음에 피타고라스의 정리에서 c의 길이를 계산하려면 제곱근을 구해야 한다.
그럼 √(루트)는 를 구현해야한다. 이때는 math 모듈의 sqrt 함수를 사용하면 편리하다. sqrt는 제곱근을 뜻하는 square root에서 따왔다.
- math.sqrt(값) n 제곱근을 반환, 값이 음수이면 에러 발생
이제 sqrt 함수까지 사용해서 p1과 p2의 거리를 구해보자.
import math
class Point2D:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Point2D(x=30, y=20) # 점1
p2 = Point2D(x=60, y=50) # 점2
a = p2.x - p1.x # 선 a의 길이
b = p2.y - p1.y # 선 b의 길이
c = math.sqrt((a * a) + (b * b)) # (a * a) + (b * b)의 제곱근을 구함
print(c) # 42.42640687119285
#실행 결과
42.42640687119285
이처럼 sqrt 함수에 값을 넣으면 해당 값의 제곱근을 구해준다. 여기서는 a의 제곱과 b의 제곱의 합을 (a * a) + (b * b)처럼 표현했는데 거듭제곱(power)을 구하는 pow 함수를 사용해도 된다.(math 모듈).
- math.pow(값, 지수) n 값을 지수만큼 거듭제곱한 값을 반환
즉, a2를 구하고 싶다면 pow(a, 2)처럼 사용한다. 앞에서 작성한 코드를 pow 함수로 다시 작성하면 다음과 같은 모양이 된다.
c = math.sqrt(math.pow(a, 2) + math.pow(b, 2))
물론 파이썬의 거듭제곱 연산자 **를 사용해도 됩니다.
c = math.sqrt((a ** 2) + (b ** 2))
만약 선의 위치를 구할 때 p2에서 p1을 빼는 것이 아닌 p1에서 p2를 빼도 상관없다. 30 - 60은 -30이고 20 - 50도 -30이다. 하지만 a2 + b2 = c2 식에서 a와 b는 같은 값을 두 번 곱하는데 음수(-)끼리 곱하면 항상 양수(+)가 되므로 부호는 상관하지 않아도 된다. 즉, 양수(+) * 양수(+) 또는 음수(-) * 음수(-) 상황밖에 없기 때문이다.
a = p1.x - p2.x # 선 a의 길이
b = p1.y - p2.y # 선 b의 길이
절댓값 함수
내장 함수 abs 또는 math 모듈의 fabs 함수를 사용하면 양수 또는 음수를 절댓값(absolute value)으로 만들 수 있다.
- abs(값)
정수는 절댓값을 정수로 반환, 실수는 절댓값을 실수로 반환
- math.fabs(값)
절댓값을 실수로 반환
절댓값 함수
파이썬에서는 각 요소에 이름을 지정해 줄 수 있는 튜플인 namedtuple을 제공한다( collections 모듈). namedtuple은 자료형 이름과 요소의 이름을 지정하면 클래스를 생성해준다. 여기서 자료형 이름은 문자열, 요소의 이름은 문자열 리스트로 넣어준다.
- 클래스 = collections.namedtuple(‘자료형이름’, [‘요소이름1’, ‘요소이름2’])
namedtuple로 생성한 클래스는 값을 넣어서 인스턴스를 만들 수 있으며 인스턴스.요소이름 또는 인스턴스[인덱스] 형식으로 요소에 접근할 수 있다.
-
인스턴스 = 클래스(값1, 값2)
-
인스턴스 = 클래스(요소이름1=값1, 요소이름2=값2)
-
인스턴스.요소이름1
-
인스턴스[인덱스]
다음은 namedtuple을 사용하여 점을 표현한 뒤 두 점의 거리를 구한다.
import math
import collections
Point2D = collections.namedtuple('Point2D', ['x', 'y']) # namedtuple로 점 표현
p1 = Point2D(x=30, y=20) # 점1
p2 = Point2D(x=60, y=50) # 점2
a = p1.x - p2.x # 선 a의 길이
b = p1.y - p2.y # 선 b의 길이
c = math.sqrt((a * a) + (b * b))
print(c) # 42.42640687119285
예제1
다음 소스 코드를 완성하여 사각형의 넓이가 출력되게 만드세요.
class Rectangle:
def __init__(self, x1, y1, x2, y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
rect = Rectangle(x1=20, y1=20, x2=40, y2=30)
①
②
③
print(area)
# 실행 결과
200
답
① width = abs(rect.x2 - rect.x1)
② height = abs(rect.y2 - rect.y1)
③ area = width * height
예제2
표준 입력으로 x, y 좌표 4개가 입력되어 Point2D 클래스의 인스턴스 리스트에 저장됩니다. 여기서 점 4개는 첫 번째 점부터 마지막 점까지 순서대로 이어져 있습니다. 다음 소스 코드를 완성하여 첫 번째 점부터 마지막 점까지 연결된 선의 길이가 출력되게 만드세요
import math
class Point2D:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
length = 0.0
p = [Point2D(), Point2D(), Point2D(), Point2D()]
p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y = map(int, input().split())
________________
________________
________________
________________
print(length)
#입력
10 10 20 20 30 30 40 40
#결과
42.42640687119285
#입력
100 100 200 200 300 300 400 400
#결과
424.26406871192853
내가 쓴 답
for i in range(len(p)-1):
a = p[i + 1].x - p[i].x
b = p[i + 1].y - p[i].y
length += math.sqrt(math.pow(a, 2) + math.pow(b, 2))
Subscribe to My Coding Practice Gym
Get the latest posts delivered right to your inbox