C library 작성
Python Code 작성
'Coding > Python 삽질기' 카테고리의 다른 글
[Python] C 함수 호출 하기 (0) | 2022.04.23 |
---|---|
[PyTorch] CUDA 설치기 (0) | 2022.02.21 |
생일 문제 (0) | 2021.06.21 |
[Python/C] 휴대폰 패턴의 가지수 (0) | 2021.02.21 |
[Python] C 함수 호출 하기 (0) | 2022.04.23 |
---|---|
[PyTorch] CUDA 설치기 (0) | 2022.02.21 |
생일 문제 (0) | 2021.06.21 |
[Python/C] 휴대폰 패턴의 가지수 (0) | 2021.02.21 |
Airbnb
https://medium.com/airbnb-engineering
Amazon
https://developer.amazon.com/blogs/appstore
AWS KR 기술 블로그
https://aws.amazon.com/ko/blogs/korea/
Dropbox
https://dropbox.tech/
Google
https://developers.googleblog.com/
Google KR
https://developers-kr.googleblog.com/
Instagram
https://instagram-engineering.com/
Netflix
https://netflixtechblog.com/
Slack
https://slack.engineering/
네이버
https://d2.naver.com/home
당근마켓 팀블로그
https://medium.com/daangn
라인
https://engineering.linecorp.com/ko/blog/
우아한형제들
https://techblog.woowahan.com/
카카오
https://tech.kakao.com/blog/
쿠팡 기술 블로그
https://medium.com/coupang-engineering
PyTorch에서 GPU를 사용해보기로 하고, 삽질한 기록을
미래의 나를 위하여, 기록하였습니다.
1. 노트북 그래픽 카드 확인
2. Pytorch 사이트에서 CUDA 버전을 확인한다.
https://pytorch.org/get-started/locally/
PyTorch
An open source machine learning framework that accelerates the path from research prototyping to production deployment.
pytorch.org
PyTorch 1.10.2에 Pip로 CUDA 10.2를 선택하면, 아래에 pip3 명령어가 보인다. 이를 사용하여 pytorch를 설치한다.
3. CUDA library 설치
PyTorch 사이트에서 확인한 CUDA 10.2 버전을 설치한다.
* 간혹 NVIDIA experience가 동작을 안하는 경우에는 아래와 같이
NVIDIA LocalSystem Controller 에서 로컬 시스템 계정 항목을 체크해 준다.
4. 파이썬을 실행해서 확인 해 본다.
[Python] C 함수 호출 하기 (0) | 2022.04.23 |
---|---|
[PyTorch] CUDA 설치기 (0) | 2022.02.21 |
생일 문제 (0) | 2021.06.21 |
[Python/C] 휴대폰 패턴의 가지수 (0) | 2021.02.21 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mandelbrot</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.02.02
// Update: 2022.02.02
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
let imageData;
let scaleX = 1.0;
let scaleY = 1.0;
let mx = 1.0;
let my = 1.0;
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
imageData = bufCtx.createImageData(canvas.width, canvas.height);
}
function _draw(x1, y1, x2, y2) {
const MAX_COUNT = 256;
// X = -3.0 ~ 3.0
// Y = -2.0 ~ 2.0
// Z = X + Yi
mx = x1 < -3.0 ? -3.0 : x1;
my = y1 < -2.0 ? -2.0 : y1;
x2 = x2 > 3.0 ? 3.0 : x2;
y2 = y2 > 2.0 ? 2.0 : y2;
let mw = x2 - x1;
let mh = y2 - y1;
console.log(x1, y1, x2, y2, " : ", mx, my, " : ", mw, mh);
scaleX = mw / imageData.width;
scaleY = mh / imageData.height;
for (let i = 0; i < imageData.height; i++) {
for (let j = 0; j < imageData.width; j++) {
let c = 0;
let x = mx + j * scaleX;
let y = my + i * scaleY;
let sx = x;
let sy = y;
for (c = 0; c < MAX_COUNT; c++) {
if (x**2 + y**2 > 4) {
break;
}
let nx = x**2 - y**2;
let ny = 2 * x * y;
x = nx + sx;
y = ny + sy;
}
let pos = 4 * (i * imageData.width + j);
let color = 3 * c / MAX_COUNT;
if (color < 1) {
imageData.data[pos+0] = 255 * color;
imageData.data[pos+1] = color;
imageData.data[pos+2] = color;
}
else if (color < 2 ) {
imageData.data[pos+0] = 255;
imageData.data[pos+1] = color;
imageData.data[pos+2] = 0;
} else {
imageData.data[pos+0] = 255;
imageData.data[pos+1] = 255;
imageData.data[pos+2] = color;
}
imageData.data[pos+3] = 255;
}
}
bufCtx.putImageData(imageData, 0, 0);
console.log("_OnDraw2()");
}
function OnDraw() {
_draw(-3.0, -2.0, 3.0, 2.0);
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
}
function rectMouseMove(event) {
// console.log("rectMouseMove");
var currentPos = getMousePosition(event);
cvs.beginPath();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
cvs.strokeStyle = pos.color;
var box = {
W: currentPos.X - pos.sx,
H: currentPos.Y - pos.sy
};
cvs.strokeRect(pos.sx, pos.sy, box.W, box.H);
cvs.stroke();
cvs.closePath();
}
function rectMouseUp(event) {
if (pos.isDraw) {
console.log("rectMouseUp");
var currentPos = getMousePosition(event);
pos.ex = currentPos.X;
pos.ey = currentPos.Y;
if (pos.sx > pos.ex) {
let t = pos.sx;
pos.sx = pos.ex;
pos.ex = t;
}
if (pos.sy > pos.ey) {
let t = pos.sy;
pos.sy = pos.ey;
pos.ey = t;
}
let sx = mx + pos.sx * scaleX;
let sy = my + pos.sy * scaleY;
let ex = mx + pos.ex * scaleX;
let ey = my + pos.ey * scaleY ;
_draw(sx, sy, ex, ey);
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
pos.isDraw = false;
}
}
function rectMouseDown(event) {
console.log("rectMouseDown");
if (pos.isDraw) {
return;
}
bufCtx.putImageData(imageData, 0, 0);
//bufCtx.drawImage(canvas, 0, 0);
pos.isDraw = true;
var startPos = getMousePosition(event);
pos.sx = startPos.X;
pos.sy = startPos.Y;
}
function mouseListener(event) {
switch (event.type) {
case "mousedown":
if (!pos.isDraw) {
pos.mouseDownAction(event);
}
break;
case "mousemove":
if (pos.isDraw) {
pos.mouseMoveAction(event);
}
break;
case "mouseup":
case "mouseout":
if (pos.isDraw) {
pos.mouseUpAction(event);
}
break;
}
}
function InitMouseEvent() {
canvas.addEventListener("mousedown", mouseListener);
canvas.addEventListener("mousemove", mouseListener);
canvas.addEventListener("mouseout", mouseListener);
canvas.addEventListener("mouseup", mouseListener);
}
function getMousePosition(event) {
var x = event.pageX - canvas.offsetLeft;
var y = event.pageY - canvas.offsetTop;
return { X: x, Y: y };
}
var pos = {
isDraw: false,
mouseDownAction: rectMouseDown,
mouseUpAction: rectMouseUp,
mouseMoveAction: rectMouseMove,
color: "rgb(255,211,25,255)",
sx: 0,
sy: 0,
ex: 0,
ey: 0
}
function onLoadPage() {
InitCanvas();
InitMouseEvent();
OnDraw();
}
window.onload = onLoadPage();
</script>
</body>
</html>
만델브로트 집합 그리기2 (0) | 2022.02.03 |
---|---|
만델브로트 집합 그리기 (0) | 2022.02.02 |
[JavaScript] 회전하는 도넛과 구 그리기 (0) | 2022.01.20 |
[JavaScript] 회전하는 도넛 그리기 (0) | 2022.01.19 |
자바스크립트로 만델브로트 집합을 구현해 보았다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mandelbrot</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.02.02
// Update: 2022.02.02
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
}
function _draw() {
let imageData = bufCtx.createImageData(canvas.width, canvas.height);
const MAX_COUNT = 255;
// X = -3.0 ~ 3.0
// Y = -2.0 ~ 2.0
// Z = X + Yi
let mx = -3.0;
let my = -2.0;
let mw = 6.0;
let mh = 4.0;
let scaleX = mw / imageData.width;
let scaleY = mh / imageData.height;
for (let i = 0; i < imageData.height; i++) {
for (let j = 0; j < imageData.width; j++) {
let c = 0;
let x = mx + j * scaleX;
let y = my + i * scaleY;
let sx = x;
let sy = y;
for (c = 0; c < MAX_COUNT; c++) {
if (x**2 + y**2 > 4) {
break;
}
let nx = x**2 - y**2;
let ny = 2 * x * y;
x = nx + sx;
y = ny + sy;
}
let pos = 4 * (i * imageData.width + j);
imageData.data[pos+0] = c;
imageData.data[pos+1] = c;
imageData.data[pos+2] = c;
imageData.data[pos+3] = 255;
}
}
bufCtx.putImageData(imageData, 0, 0);
}
function OnDraw() {
_draw();
cvs.beginPath();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
}
function onLoadPage() {
InitCanvas();
OnDraw();
}
window.onload = onLoadPage();
</script>
</body>
</html>
만델브로트 집합 그리기2 (0) | 2022.02.03 |
---|---|
만델브로트 집합 그리기 (0) | 2022.02.02 |
[JavaScript] 회전하는 도넛과 구 그리기 (0) | 2022.01.20 |
[JavaScript] 회전하는 도넛 그리기 (0) | 2022.01.19 |
소스는 아래와 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sphere</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.01.16
// Update: 2022.01.18
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
let thetaX = 0;
let thetaZ = 0;
let maxSize = 0;
let dimen = 12;
let ox = 0;
let oy = 0;
let R1 = 1; // 원의 반지름
let R2 = 1; // 회전 중심과의 거리
let R3 = 1;
let ZZ2 = 5000;
let SIN = [];
let COS = [];
function InitValue() {
for (let i = 0; i < 628; i++) {
SIN[i] = Math.sin(i / 100);
COS[i] = Math.cos(i / 100);
}
}
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
console.log(">Width:", width);
console.log(">Heigth:", height);
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
maxSize = canvas.height < canvas.width ? canvas.height : canvas.width;
ox = canvas.width / 2;
oy = canvas.height / 2;
R1 = maxSize/20; // 원의 반지름
R2 = maxSize/10; // 회전 중심과의 거리
R3 = maxSize/10;
}
function drawCircle(x, y, c, r) {
if (c <= 0 || c >= 255){
console.log(c);
}
bufCtx.beginPath();
bufCtx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
bufCtx.strokeStyle = "rgb(255, 255, 255)";
bufCtx.arc(x, y, r, 0, Math.PI * 2);
bufCtx.stroke();
bufCtx.fill();
bufCtx.closePath();
}
function _draw() {
if (maxSize == 0) {
return;
}
// 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
// z:x = z':x'
// z:y = z':y'
// x' = xz'/z, y' = yz'/z
// z' = z1
// x', y' = xz1/z, yz1/z
// z의 최대거리 z2 = 1000이라 하면
// x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
// x 의 최대 값은 R1 + R2
// x' = Z1(R1+R2)/z2 = height * 0.4
// Z1 = Z2 * height * 0.4 / (R1+R2)
let points = [];
_drawDoughnut(points);
_drawSphere(points);
bufCtx.strokeStyle = "black";
bufCtx.fillStyle = "black";
bufCtx.fillRect(0, 0, canvas.width, canvas.height);
points.forEach(e => drawCircle(e[0], e[1], e[2], 1));
thetaX = (thetaX + 2) % 629;
thetaZ = (thetaZ + 2) % 629;
}
function _drawDoughnut(points) {
// 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
// z:x = z':x'
// z:y = z':y'
// x' = xz'/z, y' = yz'/z
// z' = z1
// x', y' = xz1/z, yz1/z
// z의 최대거리 z2 = 5000이라 하면
// x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
// x 의 최대 값은 R1 + R2
// x' = Z1(R1+R2)/z2 = height * 0.4
// Z1 = Z2 * height * 0.4 / (R1+R2)
let ZZ1 = maxSize * ZZ2 * 0.4 / (R1 + R2);
for (let i = 0; i < 628; i += dimen) {
let x1 = COS[i] * R1 + R2;
let y1 = SIN[i] * R1;
let nx1 = COS[i];
let ny1 = SIN[i];
for (let j = 0; j < 628; j += dimen) {
// Y축 회전
let x2 = x1 * COS[j];
let y2 = y1;
let z2 = x1 * SIN[j];
let nx2 = nx1 * COS[j];
let ny2 = ny1;
let nz2 = nx1 * SIN[j];
// X축 회전
let x3 = x2;
let y3 = y2 * COS[thetaX] - z2 * SIN[thetaX];
let z3 = y2 * SIN[thetaX] + z2 * COS[thetaX];
let nx3 = nx2;
let ny3 = ny2 * COS[thetaX] - nz2 * SIN[thetaX];
let nz3 = ny2 * SIN[thetaX] + nz2 * COS[thetaX];
// Z축 회전
let x4 = x3 * COS[thetaZ] - y3 * SIN[thetaZ];
let y4 = x3 * SIN[thetaZ] + y3 * COS[thetaZ];
let z4 = ZZ2 * 2 + z3;
let nx4 = nx3 * COS[thetaZ] - ny3 * SIN[thetaZ];
let ny4 = nx3 * SIN[thetaZ] + ny3 * COS[thetaZ];
let nz4 = nz3;
// 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
// 광원 위치는 (0, 0, -1)
let lx = 0;
let ly = 0;
let lz = -1;
let light = nx4 * lx + ny4 * ly + nz4 * lz;
if (light > 0) {
let color = Math.round(light * 255);
// x' = xz'/z, y' = yz'/z
let xp = Math.floor(x4 * ZZ1 / z4);
let yp = Math.floor(-y4 * ZZ1 / z4);
points.push([xp + ox, yp + oy, 255-color]);
}
}
}
}
function _drawSphere(points) {
// 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
// z:x = z':x'
// z:y = z':y'
// x' = xz'/z, y' = yz'/z
// z' = z1
// x', y' = xz1/z, yz1/z
// z의 최대거리 z2 = 1000이라 하면
// x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
// x 의 최대 값은 R1 + R2
// x' = Z1(R1+R2)/z2 = height * 0.4
// Z1 = Z2 * height * 0.4 / (R1+R2)
ZZ1 = maxSize * ZZ2 * 0.4 / (R1 + R2 + R3);
for (let i = 0; i < 628; i += dimen) {
let x1 = COS[i] * R1;
let y1 = SIN[i] * R1;
let nx1 = COS[i];
let ny1 = SIN[i];
for (let j = 0; j < 628; j += dimen) {
// Y축 회전
let x2 = x1 * COS[j];
let y2 = y1;
let z2 = x1 * SIN[j];
let nx2 = nx1 * COS[j];
let ny2 = ny1;
let nz2 = nx1 * SIN[j];
// Z축 회전
let x3 = x2 * COS[thetaX] - y2 * SIN[thetaX];
let y3 = x2 * SIN[thetaX] + y2 * COS[thetaX];
let z3 = z2;
let nx3 = nx2 * COS[thetaX] - ny2 * SIN[thetaX];
let ny3 = nx2 * SIN[thetaX] + ny2 * COS[thetaX];
let nz3 = nz2;
// X축 회전
let x4 = x3 + R2 + R3;
let y4 = y3 * COS[thetaX] - z3 * SIN[thetaX];
let z4 = y3 * SIN[thetaX] + z3 * COS[thetaX];
let nx4 = nx3;
let ny4 = ny3 * COS[thetaX] - nz3 * SIN[thetaX];
let nz4 = ny3 * SIN[thetaX] + nz3 * COS[thetaX];
// Z축 시계 방향 회전
let x5 = x4 * COS[thetaZ] + y4 * SIN[thetaZ];
let y5 = -x4 * SIN[thetaZ] + y4 * COS[thetaZ];
let z5 = ZZ2 + z4;
let nx5 = nx4 * COS[thetaZ] + ny4 * SIN[thetaZ];
let ny5 = -nx4 * SIN[thetaZ] + ny4 * COS[thetaZ];
let nz5 = nz4;
// 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
// 광원 위치는 (0, 0, -1)
let lx = 0;
let ly = 0;
let lz = -1;
let light = nx5 * lx + ny5 * ly + nz5 * lz;
if (light > 0) {
let color = Math.round(light * 255);
// x' = xz'/z, y' = yz'/z
let xp = Math.floor(x5 * ZZ1 / z5);
let yp = Math.floor(-y5 * ZZ1 / z5);
points.push([xp + ox, yp + oy, 255-color]);
}
}
}
}
function OnDraw() {
_draw();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
}
function onLoadPage() {
InitValue();
InitCanvas();
OnDraw();
setInterval(OnDraw, 50);
}
window.onload = onLoadPage();
</script>
</body>
</html>
만델브로트 집합 그리기 (0) | 2022.02.02 |
---|---|
[JavaScript] 회전하는 도넛과 구 그리기 (0) | 2022.01.20 |
[JavaScript] 회전하는 도넛 그리기 (0) | 2022.01.19 |
[JavaScript] 회전하는 구 그리기 (0) | 2022.01.19 |
유튜브에서본 회전 하는 3D 도넛을 구현해 보았다.
코드는 아래와 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3D doughnut</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.01.16
// Update: 2022.01.18
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
let thetaX = 127;
let thetaZ = 0;
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
}
function drawCircle(x, y, c, r) {
if (c <= 0 || c >= 255){
console.log(c);
}
bufCtx.beginPath();
bufCtx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
bufCtx.strokeStyle = "rgb(255, 255, 255)";
bufCtx.arc(x, y, r, 0, Math.PI * 2);
bufCtx.stroke();
bufCtx.fill();
bufCtx.closePath();
}
function _draw() {
let maxSize = canvas.height < canvas.width ? canvas.height : canvas.width;
let dimen = 8;
let ox = canvas.width / 2;
let oy = canvas.height / 2;
let R1 = maxSize/20; // 원의 반지름
let R2 = maxSize/10; // Y축으로 회전하기 위한 반경
// 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
// z:x = z':x'
// z:y = z':y'
// x' = xz'/z, y' = yz'/z
// z' = z1
// x', y' = xz1/z, yz1/z
// z의 최대거리 z2 = 5000이라 하면
// x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
// x 의 최대 값은 R1 + R2
// x' = Z1(R1+R2)/z2 = height * 0.4
// Z1 = Z2 * height * 0.4 / (R1+R2)
let ZZ2 = 5000;
let ZZ1 = maxSize * ZZ2 * 0.4 / (R1 + R2);
let points = [];
for (let i = 0; i < 628; i += dimen) {
let x1 = Math.cos(i/100) * R1 + R2;
let y1 = Math.sin(i/100) * R1;
let nx1 = Math.cos(i/100);
let ny1 = Math.sin(i/100);
for (let j = 0; j < 628; j += dimen) {
// Y축 회전
let x2 = x1 * Math.cos(j/100);
let y2 = y1;
let z2 = x1 * Math.sin(j/100);
let nx2 = nx1 * Math.cos(j/100);
let ny2 = ny1;
let nz2 = nx1 * Math.sin(j/100);
// X축 회전
let x3 = x2;
let y3 = y2 * Math.cos(thetaX/100) - z2 * Math.sin(thetaX/100);
let z3 = y2 * Math.sin(thetaX/100) + z2 * Math.cos(thetaX/100);
let nx3 = nx2;
let ny3 = ny2 * Math.cos(thetaX/100) - nz2 * Math.sin(thetaX/100);
let nz3 = ny2 * Math.sin(thetaX/100) + nz2 * Math.cos(thetaX/100);
// Z축 회전
let x4 = x3 * Math.cos(thetaZ/100) - y3 * Math.sin(thetaZ/100);
let y4 = x3 * Math.sin(thetaZ/100) + y3 * Math.cos(thetaZ/100);
let z4 = ZZ2 + z3;
let nx4 = nx3 * Math.cos(thetaZ/100) - ny3 * Math.sin(thetaZ/100);
let ny4 = nx3 * Math.sin(thetaZ/100) + ny3 * Math.cos(thetaZ/100);
let nz4 = nz3;
// 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
// 광원 위치는 (0, 0, -1)
let lx = 0;
let ly = 0;
let lz = -1;
let light = nx4 * lx + ny4 * ly + nz4 * lz;
if (light > 0) {
let color = Math.round(light * 255);
// x' = xz'/z, y' = yz'/z
let xp = Math.floor(x4 * ZZ1 / z4);
let yp = Math.floor(-y4 * ZZ1 / z4);
points.push([xp + ox, yp + oy, 255-color]);
}
}
}
bufCtx.beginPath();
bufCtx.strokeStyle = "black";
bufCtx.fillStyle = "black";
bufCtx.fill();
bufCtx.fillRect(0, 0, canvas.width, canvas.height);
bufCtx.closePath();
bufCtx.stroke();
points.forEach(e => drawCircle(e[0], e[1], e[2], 1));
thetaX = (thetaX + 2) % 629;
thetaZ = (thetaZ + 2) % 629;
}
function OnDraw() {
_draw();
cvs.beginPath();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
console.log(">OnDraw()");
}
function onLoadPage() {
InitCanvas();
OnDraw();
setInterval(OnDraw, 50);
}
window.onload = onLoadPage();
</script>
</body>
</html>
[JavaScript] 회전하는 도넛과 구 그리기 (0) | 2022.01.20 |
---|---|
[JavaScript] 회전하는 도넛 그리기 (0) | 2022.01.19 |
[JavaScript] 회전하는 구 그리기 (0) | 2022.01.19 |
[Javascript] 좋은 글 링크 모음 (0) | 2021.10.16 |
유튜브에서 회전하는 도넛 영상을 보고, 회전하는 구를 그려 보았다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sphere</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.01.18
// Update: 2022.01.19
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
let thetaX = 0;
let thetaZ = 0;
let SIN = [];
let COS = [];
function InitValue() {
for (let i = 0; i < 628; i++) {
SIN[i] = Math.sin(i / 100);
COS[i] = Math.cos(i / 100);
}
}
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
console.log(">Width:", width);
console.log(">Heigth:", height);
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
}
function drawCircle(x, y, c, r) {
bufCtx.beginPath();
bufCtx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
bufCtx.strokeStyle = "rgb(255, 255, 255)";
bufCtx.arc(x, y, r, 0, Math.PI * 2);
bufCtx.stroke();
bufCtx.fill();
bufCtx.closePath();
}
function _draw() {
let maxSize = canvas.height < canvas.width ? canvas.height : canvas.width;
let dimen = 8;
let ox = canvas.width / 2;
let oy = canvas.height / 2;
let R1 = maxSize/20;
let ZZ1 = maxSize * 1000 * 0.4 / R1;
let points = [];
for (let i = 0; i < 628; i += dimen) {
let a = COS[i];
let b = SIN[i];
for (let j = 0; j < 628; j += dimen) {
let c = COS[j];
let d = SIN[j];
let e = COS[thetaX];
let f = SIN[thetaX];
let g = COS[thetaZ];
let h = SIN[thetaZ];
let k = b * R1 * e - a * R1 * d * f;
let x4 = a * R1 * c * g - k * h;
let y4 = a * R1 * c * h + k * g;
let z4 = ZZ1 / (1000 + b * R1 * f + a * R1 * d * e);
let light = (b * f + a * d * e);
if (light > 0) {
let color = Math.round(light * 255);
let xp = Math.floor(x4 * z4 + ox);
let yp = Math.floor(-y4 * z4 + oy);
points.push([xp, yp, 255-color]);
}
}
}
bufCtx.strokeStyle = "black";
bufCtx.fillStyle = "black";
bufCtx.fillRect(0, 0, canvas.width, canvas.height);
points.forEach(e => drawCircle(e[0], e[1], e[2], 1));
thetaX = (thetaX + 2) % 629;
thetaZ = (thetaZ + 2) % 629;
}
function OnDraw() {
let startTime = new Date();
_draw();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
console.log("Elapsed time: " + (new Date() - startTime));
}
function onLoadPage() {
InitValue();
InitCanvas();
OnDraw();
setInterval(OnDraw, 50);
}
window.onload = onLoadPage();
</script>
</body>
</html>
아래 코드에서 _drawSphere()를 채워 나갑니다.
하기 HTML 코드는 좋은 예제가 아닙니다. HTML 관련은 인터넷에 있는 좋은 코드를 참고 하시기 바랍니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sphere</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
console.log(">Width:", width);
console.log(">Heigth:", height);
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
}
function _drawSphere() {
}
function OnDraw() {
let startTime = new Date();
bufCtx.strokeStyle = "black";
bufCtx.fillStyle = "black";
bufCtx.fillRect(0, 0, canvas.width, canvas.height);
_drawSphere();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
console.log("Elapsed time: " + (new Date() - startTime));
}
function onLoadPage() {
InitCanvas();
OnDraw();
setInterval(OnDraw, 50);
}
window.onload = onLoadPage();
</script>
</body>
</html>
원점을 기준으로 지름 r인 원은 아래 수식으로 표현 할 수 있습니다.
이때, x, y는 아래와 같이 구 할 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sphere</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<style>
canvas {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div align='center'>
<canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
// Start: 2022.01.16
// Update: 2022.01.18
let cvs;
let canvas;
let bufCanvas;
let bufCtx;
let thetaX = 0;
let thetaZ = 0;
function InitCanvas() {
height = window.innerHeight;
width = window.innerWidth;
console.log(">Width:", width);
console.log(">Heigth:", height);
canvas = document.getElementById("canvas");
canvas.width = width;
canvas.height = height;
cvs = canvas.getContext("2d");
bufCanvas = document.createElement("canvas");
bufCanvas.width = canvas.width;
bufCanvas.height = canvas.height;
bufCtx = bufCanvas.getContext("2d");
}
function drawCircle(x, y, c, r) {
bufCtx.beginPath();
bufCtx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
bufCtx.strokeStyle = "rgb(255, 255, 255)";
bufCtx.arc(x, y, r, 0, Math.PI * 2);
bufCtx.stroke();
bufCtx.fill();
bufCtx.closePath();
}
function _draw() {
let maxSize = canvas.height < canvas.width ? canvas.height : canvas.width;
let dimen = 8;
let ox = canvas.width / 2;
let oy = canvas.height / 2;
let R1 = maxSize/20; // 원의 반지름
// 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
// z:x = z':x'
// z:y = z':y'
// x' = xz'/z, y' = yz'/z
// z' = z1
// x', y' = xz1/z, yz1/z
// z의 최대거리 z2 = 1000이라 하면
// x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
// x 의 최대 값은 R1 + R2
// x' = Z1(R1+R2)/z2 = height * 0.4
// Z1 = Z2 * height * 0.4 / (R1+R2)
let ZZ2 = 1000;
let ZZ1 = maxSize * ZZ2 * 0.4 / R1;
let points = [];
for (let i = 0; i < 628; i += dimen) {
let x1 = Math.cos(i/100) * R1;
let y1 = Math.sin(i/100) * R1;
let nx1 = Math.cos(i/100);
let ny1 = Math.sin(i/100);
for (let j = 0; j < 628; j += dimen) {
// Y축 회전
let x2 = x1 * Math.cos(j/100);
let y2 = y1;
let z2 = x1 * Math.sin(j/100);
let nx2 = nx1 * Math.cos(j/100);
let ny2 = ny1;
let nz2 = nx1 * Math.sin(j/100);
// X축 회전
let x3 = x2;
let y3 = y2 * Math.cos(thetaX/100) - z2 * Math.sin(thetaX/100);
let z3 = y2 * Math.sin(thetaX/100) + z2 * Math.cos(thetaX/100);
let nx3 = nx2;
let ny3 = ny2 * Math.cos(thetaX/100) - nz2 * Math.sin(thetaX/100);
let nz3 = ny2 * Math.sin(thetaX/100) + nz2 * Math.cos(thetaX/100);
// Z축 회전
let x4 = x3 * Math.cos(thetaZ/100) - y3 * Math.sin(thetaZ/100);
let y4 = x3 * Math.sin(thetaZ/100) + y3 * Math.cos(thetaZ/100);
let z4 = ZZ2 + z3;
let nx4 = nx3 * Math.cos(thetaZ/100) - ny3 * Math.sin(thetaZ/100);
let ny4 = nx3 * Math.sin(thetaZ/100) + ny3 * Math.cos(thetaZ/100);
let nz4 = nz3;
// 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
// 광원 위치는 (0, 0, -1)
let lx = 0;
let ly = 0;
let lz = -1;
let light = nx4 * lx + ny4 * ly + nz4 * lz;
if (light > 0) {
let color = Math.round(light * 255);
// x' = xz'/z, y' = yz'/z
let xp = Math.floor(x4 * ZZ1 / z4);
let yp = Math.floor(-y4 * ZZ1 / z4);
points.push([xp + ox, yp + oy, 255-color]);
}
}
}
bufCtx.strokeStyle = "black";
bufCtx.fillStyle = "black";
bufCtx.fillRect(0, 0, canvas.width, canvas.height);
points.forEach(e => drawCircle(e[0], e[1], e[2], 1));
thetaX = (thetaX + 2) % 629;
thetaZ = (thetaZ + 2) % 629;
}
function OnDraw() {
_draw();
cvs.clearRect(0, 0, canvas.width, canvas.height);
cvs.drawImage(bufCanvas, 0, 0);
}
function onLoadPage() {
InitCanvas();
OnDraw();
setInterval(OnDraw, 50);
}
window.onload = onLoadPage();
</script>
</body>
</html>
[JavaScript] 회전하는 도넛 그리기 (0) | 2022.01.19 |
---|---|
[JavaScript] 회전하는 구 그리기 (0) | 2022.01.19 |
[Javascript] 좋은 글 링크 모음 (0) | 2021.10.16 |
[Javascript] 3D programming 기초 링크 (일본어) (0) | 2021.02.13 |
TextView에서 한 줄에 표시되는 글자수를 계산 하는 코드
var textView: TextView = findViewById(R.id.textView)
val COL : Int = Math.round(textView.width / textView.paint.measureText("가나다라마.") * 6)
그런데 OnCreate에서 위 함수를 사용하면 0이 나온다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.textviewer)
val vto: ViewTreeObserver = textView.getViewTreeObserver()
vto.addOnGlobalLayoutListener {
if (getWidthCount < 1) {
getWidthCount++
val COL : Int = Math.round(textView.width / textView.paint.measureText("가나다라마.") * 6)
Log.i(TAG, "getWidth:" + COL)
}
}
}
이 경우 위와 같이, 코드를 추가해 주면 된다.
[Android] TextView 한 줄의 글자 수 계산하기 (0) | 2021.10.24 |
---|---|
[Android][Unit Test] 테스트시 파일 읽기 (0) | 2021.10.17 |
[Java] Solitaire 만들기 2 (자바 솔리테어 만들기) (0) | 2020.05.14 |
[Android] Mahjong 만들기 (안드로이드 마작 만들기) (0) | 2020.04.12 |
Unit test에서 Test sample 파일을 읽어서 테스트 하는 방법
1. test 폴더에 resources 폴더를 만들고 테스트 파일을 넣는다
2. 아래와 같이 코드를 작성한다.
@Test
public void encrypt() throws URISyntaxException {
File file = new File(getClass().getResource("/1.txt").toURI());
assert(file != null);
URL unavailableURL = getClass().getResource("/unavilable.txt");
assert(unavailableURL == null);
}
[Android] TextView 한 줄의 글자 수 계산하기 (0) | 2021.10.24 |
---|---|
[Android][Unit Test] 테스트시 파일 읽기 (0) | 2021.10.17 |
[Java] Solitaire 만들기 2 (자바 솔리테어 만들기) (0) | 2020.05.14 |
[Android] Mahjong 만들기 (안드로이드 마작 만들기) (0) | 2020.04.12 |
댓글을 달아 주세요