sharedate:*
로 검색 창에서 검색하면 된다.
'My Life > Mobile' 카테고리의 다른 글
[갤럭시] eSim 알뜰 폰 가입하기 (0) | 2022.09.07 |
---|---|
[Android] 안드로이드에서 앱에서 인터넷 링크가 안 열릴 때 (0) | 2020.10.13 |
모아키 사용법 (2) | 2020.10.08 |
sharedate:*
로 검색 창에서 검색하면 된다.
[갤럭시] eSim 알뜰 폰 가입하기 (0) | 2022.09.07 |
---|---|
[Android] 안드로이드에서 앱에서 인터넷 링크가 안 열릴 때 (0) | 2020.10.13 |
모아키 사용법 (2) | 2020.10.08 |
PyTorch에서 GPU를 사용해보기로 하고, 삽질한 기록을
미래의 나를 위하여, 기록하였습니다.
1. 노트북 그래픽 카드 확인
2. Pytorch 사이트에서 CUDA 버전을 확인한다.
https://pytorch.org/get-started/locally/
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 |
---|---|
생일 문제 (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>
JsCalculator 개인정보처리방침 / JsCalculator Privacy Policy (0) | 2022.08.24 |
---|---|
만델브로트 집합 그리기 (0) | 2022.02.02 |
[JavaScript] 회전하는 도넛과 구 그리기 (0) | 2022.01.20 |
자바스크립트로 만델브로트 집합을 구현해 보았다.
<!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 |
---|---|
[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.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) | 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) | 2021.10.16 |
[Javascript] 3D programming 기초 링크 (일본어) (0) | 2021.02.13 |
청소의 귀차니즘으로 인하여, 비스포크 제트 봇을 구매 후 기록한 내돈내산 사용기 입니다.
박스를 열면 아래와 같이 이쁜 녀석이 나온다.
IT 스터디 / 사이드 프로젝트 구하기 전에 읽어 보면 좋은 글들 (0) | 2022.12.30 |
---|
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)
}
}
}
이 경우 위와 같이, 코드를 추가해 주면 된다.
ImageMatch 개인 정보 처리 방침 / ImageMatch Privacy Policy (0) | 2022.11.16 |
---|---|
[Android][Unit Test] 테스트시 파일 읽기 (0) | 2021.10.17 |
[Java] Solitaire 만들기 2 (자바 솔리테어 만들기) (0) | 2020.05.14 |
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 |
---|---|
[Java] Solitaire 만들기 2 (자바 솔리테어 만들기) (0) | 2020.05.14 |
[Android] Mahjong 만들기 (안드로이드 마작 만들기) (0) | 2020.04.12 |