koodev

'전체 글'에 해당되는 글 75건

  1. Equivalence relations (2) - Bar 표현식
  2. Equivalence relations (1)
  3. OpenGL로 원 그리기 1

Equivalence relations (2) - Bar 표현식

Math

어떤 집합 S에 Equivalence Relation이나 Partition이 있다고 해 보자. 이 상황에서 각 엘리먼트가 Equivalence Class(혹은 Partition에 의해 나눠진 부분집합)인 새로운 집합 S를 정의할 수 있다. Equivalence Class들로 이루어진 집합이 되는 것이다. 더 나아가서 a를 포함하는 Equivalence Class가 있을 경우 이를 a라고 표기할 수 있다. aS의 엘리먼트 중 하나인 것이다.

위의 상황을 아래와 같은 natural surjective map으로 표현할 수 있다. natural surjective map은 전사함수인데, codomain(정의역) = range(치역) 인 함수를 말한다.

SS, which sends
aa

예를 들어 S = ℤ 이고, S의 엘리먼트가 (Even)과 (Odd)로 이루어져 있다면, 0 = 2 = 4 = ... 가 될 것이다. 즉, 이들 중 어느것이라도 집합 (Even)을 나타낼 수 있다.

ℤ ⟶ {(Even), (Odd)}

위와 같은 상황을 두 가지 방식으로 생각해 볼 수 있겠다.

집합 S의 엘리먼트들을 Partition으로 나눠진 부분집합 중 한 곳에 쌓아놓는다고 보고 각각에 쌓인 더미들(piles)이 또 다른 집합 S 를 형성한다고 생각하는 것이다. SSS의 엘리먼트들을 해당하는 더미(pile)로 옮기는 매핑인 것이다.

또는 이러한 매핑을 S에서 서로 모이는 것끼리는 '같다'라고 생각해 볼 수 있다. 즉, a ~ bS에서는 a = b 를 의미한다고 보는 것이다. 이 관점에서 보면 두 집합 SS는 서로 대응되는(correspond) 관계인 것이다. 단, S에서 엘리먼트끼리 '같다'라는 의미가 좀 더 강할 것이다. 아래의 표현으로 좀 더 명확하게 설명될 수 있을 것 같다.

a = b means a ~ b

위와 같은 bar 표현식의 단점이라고 한다면, 여러 심볼들이 나타내는 것들이 서로 겹칠 수 있다는 점이다. 이에 대하여 각 Equivalence Class의 대표 표현식만 쓰는 방법이 있다. 예를 들면, (Even)을 0 으로, (Odd)를 1 으로만 쓰는 것이다.

{(Even), (Odd)} = {0, 1}

물론 첫 번째 방식(매핑에 의해 더미로 쌓인다고 생각하는 것)이 좀 더 눈에 잘 들어올 수는 있겠으나, 어떤 경우에는 두 번째 방식(bar 표현식)이 더 적합하다. 첫 번째 방식은 표현하기에는 어렵고 손이 많이 가는 반면, (짝수/홀수를 생각해보자) 두 번째 방식은 수학적인 표현식에 집어넣기 편하기 때문이다.

'Math' 카테고리의 다른 글

Congruence Relation & Coset  (0) 2017.06.10
Equivalence relations (3) - fibres  (0) 2017.06.08
Equivalence relations (1)  (0) 2017.05.31
Homomorphisms (2): image, kernel and normal subgroup  (0) 2017.05.24
Homomorphisms (1)  (0) 2017.05.22

Equivalence relations (1)

Math

Equivalence Relation은 우리말로 하면 '동치관계'이다.

수학적인 구조를 만드는 기본적인 방법중에 하나는 집합 S에서부터 시작하여 S안의 특정 엘리먼트들을 같은 범주로 두는 새로운 집합을 생성하는것이다. 편가르기? 예를 들면, 정수 집합을 짝수와 홀수 두 개의 집합으로 나눌 수 있을 것이다. 또는 평면상에서 합동인 삼각형(Congruent Triangle)들을 지리적으로 동일한 오브젝트로 볼 수도 있다.

어떤 집합 S가 있을 때, Partition P of SS를 겹치지 않는 부분집합으로 나누는 것을 의미한다.

S = union of disjoint, nonempty subsets

예를 들면, 아래 집합은 집합 {1, 2, 3, 4, 5}의 Partition이다.

{1, 3}, {2, 5}, {4}

그리고 Equivalence Relation on SS에서 특정 엘리먼트들끼리의 관계를 의미한다. 이를 a ~ b 이렇게 쓰고 Equivalence of a and b라고 부른다.

Equivalence Relation은 아래와 같은 조건이 붙는다.

  1. transitive: If a ~ b and b ~ c, then a ~ c
  2. symmetric: If a ~ b, then b ~ a
  3. reflexive: a ~ a for all aS

예를 들면, 합동인 삼각형(Congruent Triangle)들은 평면상의 삼각형들의 집합 S에서 Equivalence Relation이 될 수 있다.

좀 더 일반적으로 들어가보자. 집합 S에서 Relation을 갖는다는 의미는 S의 엘리먼트 두개를 짝지어 놓은 집합 S × S의 부분집합 R과 같다. 여기서 Ra ~ b인 (a, b) 짝들로 구성된다. 그럼 부분집합의 관점에서 위에서 살펴본 Relation의 Axiom들을 아래와 같이 써볼 수 있다.

  1. if (a, b) ∈ R and (b, c) ∈ R, then (a, c) ∈ R
  2. if (a, b) ∈ R, then (b, a) ∈ R
  3. (a, a) ∈ R for all a

Partition of S라는 말과 Equivalence Releation on S라는 말은 논리적으로는 서로 equivalent(동등)하여 실제로는 둘 중에 하나만 대표로 사용된다. 즉 주어진 Partition of S에서 ab가 Partion의 같은 부분집합에 놓여 있을 경우 이를 a ~ b라고 맺은 Equivalence Relation R을 정의할 수 있다. 위의 Axiom들을 모두 만족하기 때문이다. 반대로, 주어진 Equivalence Relation R에서도 Partition P를 다음과 같이 정의할 수 있다: 엘리먼트 aa ~ b인 모든 엘리먼트 b를 포함하는 부분집합. 이런 부분집합을 Equivalence Class of a 라고 하고, S가 Euqivalence Class로 Partition 되었다고도 한다.

Equivalent Relation이 집합 S에서 Partition을 만든다는 의미를 확인해보자. CaaS인 Equivalence Class라고 하자. 즉, Caa ~ b인 모든 b를 포함한다.

Ca = {bS | a ~ b}

위의 Axiom들 중 reflexive에 의해 aCa 가 되기 때문에 모든 Ca 클래스들은 nonempty이다. 또한 aS의 어떤 엘리먼트도 될 수 있기 때문에 Ca 클래스들이 모이면 집합 S를 커버한다.

이어서 서로다른 Equivalence Class 들은 겹쳐서는 안된다는 속성을 확인해야 한다. 여기서 헷갈릴 수도 있는게, symmetric에 의해서 a ~ bb ~ a 도 되어, bCa 가 될 수 있다. 그런데 bCb 이기도 하기 때문에 서로 다른 Equivalence Class 들이 겹치는 문제가 발생한다. 하지만 사실은 두 클래스가 동일하다. 이어서 아래 내용을 살펴보자.

Ca와 Cb가 공통의 엘리먼트 d를 포함한다고 하자. 그러면, Ca = Cb 이다.

우선 a ~ b 이면 Ca = Cb 이라는 것을 확인해보자. xCb의 임의의 엘리먼트라고 하면, b ~ x 이다. 그러면 a ~ b 이기 때문에 transitivity에 의하여, a ~ x 이며 xCa 가 된다. 따라서 CbCa 가 된다. ab의 순서를 바꾸어도 마찬가지이기 때문에 CaCb 도 성립한다.

그리고 dCaCb의 공통의 엘리먼트라면, a ~ d 이면서 b ~ d 가 된다. 그러면 transitive에 의하여 a ~ b 가 되면서 위에서 밝힌 CbCaCaCb에 의해 Ca = Cd = Cb 가 성립된다(끝).

다시 말해서 각 Equivalence Class들간에 겹치는 엘리먼트가 있다면, 두 클래스가 완전히 동일하게 되므로 한 집합에서 겹치는 Equivalence Class가 생길 수 없게 되는 것이다.

'Math' 카테고리의 다른 글

Equivalence relations (3) - fibres  (0) 2017.06.08
Equivalence relations (2) - Bar 표현식  (0) 2017.06.02
Homomorphisms (2): image, kernel and normal subgroup  (0) 2017.05.24
Homomorphisms (1)  (0) 2017.05.22
Automorphism and conjugation  (0) 2017.05.18

OpenGL로 원 그리기

Programming

OpenGL로 원을 그리려면 어떻게 해야 할까? OpenGL primitive에는 원이 없고 점이나 선, 삼각형 등만 그릴 수 있다. 그러면 점근적인 접근방식으로 삼각형을 여러개 이어서 원 모양으로 그릴 수 있을 것이다. 그렇지만 이 방식은 정교하게 하려하면 할수록 더 많은 점들이 필요하다. 여기서는 점 4개 만으로 그릴 수 있는 방법을 정리해 보았다.

우선 그릴 원을 정의해 보자. 구현을 단순하게 하기 위해서 NDC(Normalized Device Coordinates)를 기반으로 해서 아래와 같이 정의해 보았다.

  • 반지름: 0.5
  • 원점좌표: (0.0, 0.0, 0.0)
  • 색깔: 외접하는 사각형의 네 귀퉁이를 빨강, 파랑, 노랑, 초록으로 하여 섞어서 보간

추가적으로 타원이 아닌 동그라미를 그리기 위해서는 그림을 그릴 윈도우의 가로세로 비율이 필요하다. 가로/세로 = 3/2 = 1.5 로 고정시킨다.

일단 원을 그리기 앞서 외접하는 사각형을 그린다. 점들의 좌표와 인덱스는 아래와 같이 정의한다.

let vertices: [GLfloat] = [
    -0.5, -0.5, +0.0, 1.0, 0.0, 0.0,
    +0.5, -0.5, +0.0, 0.0, 1.0, 0.0,
    +0.5, +0.5, +0.0, 0.0, 0.0, 1.0,
    -0.5, +0.5, +0.0, 1.0, 1.0, 0.0,
]
let indices: [GLuint] = [
    0, 1, 2,
    0, 2, 3
]

아래는 Vertex shader고,

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
out vec3 ourColor;
void main()
{
  gl_Position = vec4(position.x, position.y, position.z, 1.0);
  ourColor = color;
}

Fragment shader는 아래와 같다.

#version 330 core
in vec3 ourColor;
out vec4 color;
void main()
{
  color = vec4(ourColor, 1.0);
}

이걸 가지고 사각형을 그리면 아래와 같이 된다. 풀 소스는 다음 링크를 참고한다:

결과는 아래 그림과 같다.

이를 기반으로 원을 그려보자. 원을 그리는 전략은 각 Fragment에서 원의 중심 좌표로부터 거리를 재서 정의한 반지름 안에 들어오면 해당하는 색을 칠하고, 거리가 너무 멀면 색을 칠하지 않는 것이다. 거리를 재기 위해서 GLSL의 내장 함수인 distance를, 반지름과 비교하여 0아님 1의 값을 내기 위해 step함수를 사용할 것이다.

우선 Vertex shader는 아래와 같다.

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
out vec3 ourColor;
out vec3 ourPosition;
void main()
{
  gl_Position = vec4(position.x, position.y, position.z, 1.0);
  ourColor = color;
  float ratio = 3.0 / 2.0;
  ourPosition = vec3(position.x * ratio, position.y, position.z);
}

그리고 Fragment shader는 아래와 같다.

#version 330 core
in vec3 ourColor;
in vec3 ourPosition;
out vec4 color;
void main()
{
  float radius = 0.5;
  vec3 origin = vec3(0.0);
  float dist = distance(origin, ourPosition);
  float alpha = step(dist, radius);
  color = vec4(ourColor, alpha);
}

그러면 아래와 같은 동그라미를 그릴 수 있다. 근데 원의 가장자리가 찌글찌글한 모양새를 (선호하는 사람도 있겠지만) 불편해 하는 사람도 있을 것이다.

가장자리에 안티알리아스 효과를 주기 위해서 step 함수를 대신하여 smoothstep 함수를 사용할 수 있다. step이 계단이라면 smoothstep은 언덕길이라고 할 수 있겠다. 아래 그림 참고.

smoothstep을 사용하는 Fragment shader는 아래와 같다.

#version 330 core
in vec3 ourColor;
in vec3 ourPosition;
out vec4 color;
void main()
{
  float radius = 0.5;
  vec3 origin = vec3(0.0);
  float dist = distance(origin, ourPosition);
  float delta = 0.01;
  float alpha = smoothstep(dist-delta, dist, radius-delta);
  color = vec4(ourColor, alpha);
}

그리고 최종 결과는 아래와 같다.

풀 소스는 다음 링크를 참고한다: CircleRenderer.swift

참고한 사이트: