public void Spin_XZAxis5() { position.Set(Position); cursor.x += (Cursor.Position.X - screenPoint.X) * sensitivity; cursor.y += (Cursor.Position.Y - screenPoint.Y) * sensitivity; cursor.x %= 360; cursor.y %= 360; cursor.y = cursor.y > 90 ? 90 : (cursor.y < -90 ? -90 : cursor.y); Cursor.Position = screenPoint; double degreeX = cursor.y * -PI; double degreeY = cursor.x * PI; double sinX = Math.Sin(degreeX); double sinY = Math.Sin(degreeY); double cosX = Math.Cos(degreeX); double cosY = Math.Cos(degreeY); bool isTargetSet = false; basisX.Set(1, 0, 0); basisY.Set(0, camSize.y - 1, 0); basisZ.Set(0, 0, 1); Spin_matrix_x(basisX.x, basisX.y, basisX.z, sinX, cosX, basisX); Spin_matrix_z(basisX.x, basisX.y, basisX.z, sinY, cosY, basisX); Spin_matrix_x(basisY.x, basisY.y, basisY.z, sinX, cosX, basisY); Spin_matrix_z(basisY.x, basisY.y, basisY.z, sinY, cosY, basisY); Spin_matrix_x(basisZ.x, basisZ.y, basisZ.z, sinX, cosX, basisZ); Spin_matrix_z(basisZ.x, basisZ.y, basisZ.z, sinY, cosY, basisZ); world.GetFrameIndex(position, PositionIndex); Parallel.For(0, camSize.z, (int k) => { Parallel.For(0, camSize.x, (int i) => { int depth = 0; board[k, i] = ' '; perspBasisX[i, k].Set(basisX).Mul(perspArray[i, k].x); perspBasisZ[i, k].Set(basisZ).Mul(perspArray[i, k].z); spinArray[i, k].Set(perspBasisX[i, k]).Add(basisY).Add(perspBasisZ[i, k]); XYZ_d delta = deltaArray[i, k].Set(spinArray[i, k]).Div(camSize.y); XYZ_d index = indexArray[i, k].Set(position); XYZ_d gap = new XYZ_d(); XYZ_d lpos = new XYZ_d(); XYZ frameIndex = new XYZ(); XYZ nextFrameIndexDelta = new XYZ(); XYZ_d target = new XYZ_d(); XYZ_d deltaSign = new XYZ_d(); if (delta.x != 0) { deltaSign.x = (Math.Abs(delta.x) / delta.x); } if (delta.y != 0) { deltaSign.y = (Math.Abs(delta.y) / delta.y); } if (delta.z != 0) { deltaSign.z = (Math.Abs(delta.z) / delta.z); } frameIndex.Set(PositionIndex); double numOfDelta = 0; for (int j = 0; j < camSize.y; j++) { if (!world.IsInFrame(frameIndex) || j == camSize.y - 1) { depth = depth < 0 ? 0 : depth > 9 ? 9 : depth; board[k, i] = level[depth]; break; } world.ConvertToFramePos(lpos.Set(index), frameIndex); if (world.IsExistPixelInFrame(frameIndex)) { if (i == camPoint.x && k == camPoint.z && !isTargetSet) { deleteFrameIndex.Set(frameIndex); addFrameIndex.Set(frameIndex).Sub(nextFrameIndexDelta); isTargetSet = true; } if (frameIndex.Equal(deleteFrameIndex)) { depth += 3; //쳐다보는 블록 색깔 } world.GetFrameIndex(index, gap); if (gridEnabled && gap.Distance(PositionIndex) < 3) //3칸블록 이내 범위있을 경우 경계선표시. { bool Xaxis = Math.Abs(lpos.x) > world.frameLength / 2 - 1; //경계선 테두리 크기 1 bool Yaxis = Math.Abs(lpos.y) > world.frameLength / 2 - 1; bool Zaxis = Math.Abs(lpos.z) > world.frameLength / 2 - 1; int inv_color = world.GetColor(frameIndex); if (inv_color > 5) { if (inv_color == 14) { inv_color = 9; } else { inv_color = 0; } } else { inv_color = 9; } inv_color += (5 - inv_color) / 5 * 2; if (Xaxis && Yaxis) { board[k, i] = level[inv_color]; break; } if (Yaxis && Zaxis) { board[k, i] = level[inv_color]; break; } if (Zaxis && Xaxis) { board[k, i] = level[inv_color]; break; } } if (world.GetColor(frameIndex) == 14) // 거울만나면 반사. { if (nextFrameIndexDelta.x != 0) { delta.x = -delta.x; deltaSign.x = -deltaSign.x; } else if (nextFrameIndexDelta.y != 0) { delta.y = -delta.y; deltaSign.y = -deltaSign.y; } else if (nextFrameIndexDelta.z != 0) { delta.z = -delta.z; deltaSign.z = -deltaSign.z; } frameIndex.Sub(nextFrameIndexDelta); // 일보후퇴 continue; } else if (world.GetColor(frameIndex) == 15) // 유리만나면 살짝 하얘지고 계속 진행. { depth = depth > 3 ? 3 : depth + 1; } else { depth += (int)(world.GetColor(frameIndex)); depth = depth < 0 ? 0 : depth > 9 ? 9 : depth; board[k, i] = level[depth]; break; } } //현위치에서 delta벡터방향으로 이동할 경우 가장 먼저 만나는 경계면 구하기. target.Set(world.frameLength / 2); target.Mul(deltaSign); //delta벡터 방향으로 이동시 접촉가능한 경계면들 구하기. target.Sub(lpos).Div(delta); //경계면들로부터 현재위치의 거리를 구하고 delta로 나누기. deltasign으로 한번 곱했었기때문에 x,y,z축 서로에 대한 정확한 비교값이 나오게된다. nextFrameIndexDelta.Set(0); if (target.x < target.y && target.x < target.z) { numOfDelta = target.x; nextFrameIndexDelta.x = (int)deltaSign.x; } else if (target.y < target.x && target.y < target.z) { numOfDelta = target.y; nextFrameIndexDelta.y = (int)deltaSign.y; } else if (target.z < target.x && target.z < target.y) { numOfDelta = target.z; nextFrameIndexDelta.z = (int)deltaSign.z; } frameIndex.Add(nextFrameIndexDelta); //가장가까운 경계면에 해당하는 블록으로 이동. index.Add(gap.Set(delta).Mul(numOfDelta)); //delta방향으로 가장 가까운 경계면으로 이동. //여기까지 수정 } }); }); rayDelta.Set(deltaArray[camPoint.x, camPoint.z]); }
public void MakeCone(XYZ_d pos, int radius, int height) { XYZ frameIndex = new XYZ(); XYZ_d temp = new XYZ_d(); XYZ_d temp2 = new XYZ_d(); XYZ_d temp3 = new XYZ_d(); double distance = 0; pos.z += height; XYZ_b color = new XYZ_b(1, 1, 1); XYZ_b color2 = new XYZ_b(color).Mul(30); double degreeX = 30 * -Math.PI / 180d; double degreeY = 0 * Math.PI / 180d; double sinX = Math.Sin(degreeX); double sinY = Math.Sin(degreeY); double cosX = Math.Cos(degreeX); double cosY = Math.Cos(degreeY); XYZ_d basisX = new XYZ_d(cosY, -sinY, 0); XYZ_d basisY = new XYZ_d(cosX * sinY, cosX * cosY, -sinX); XYZ_d basisZ = new XYZ_d(sinX * sinY, sinX * cosY, cosX); for (int i = -radius - 1; i < radius + 1; i++) { for (int j = -radius - 1; j < radius + 1; j++) { for (int k = -height - 1; k < -height / 2 + 1; k++) { temp.Set(pos).Add(i, j, k); frameIndex = temp.ToXYZ(); ConvertToInfinity(frameIndex); SetBlock(frameIndex, true); SetColor(frameIndex, 0, 0, 0); SetRender(frameIndex, renderer_block); //SetColor(frameIndex,1,0,0); } } } for (int i = -radius; i < radius; i++) { for (int j = -radius; j < radius; j++) { for (int k = -height; k < -height / 2; k++) { temp.Set(pos).Add(i, j, k); frameIndex = temp.ToXYZ(); ConvertToInfinity(frameIndex); SetBlock(frameIndex, false); SetRender(frameIndex, renderer_air); //SetColor(frameIndex,1,0,0); } } } //frameIndex = pos.ToXYZ(); //ConvertToInfinity(frameIndex); //frameIndex.z -= height - 10; temp.Set(pos).Sub(0, 10, height - 10); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { for (int k = -2; k <= 2; k++) { temp2.Set(temp).Add(i, j, k); frameIndex = temp2.ToXYZ(); ConvertToInfinity(frameIndex); SetBlock(frameIndex, true); SetRender(frameIndex, renderer_block); } } } for (int i = -radius; i < radius; i++) { for (int j = -radius; j < radius; j++) { temp.Set(pos).Add(i, j, 0); distance = pos.Distance(temp); if (distance < radius) { frameIndex = temp.ToXYZ(); ConvertToInfinity(frameIndex); //SetColor(frameIndex,color); temp2.Set(temp).Sub(pos).Add(0, 0, height).Div(height); temp2.Set(basisX.x * temp2.x + basisY.x * temp2.y + basisZ.x * temp2.z, basisX.y * temp2.x + basisY.y * temp2.y + basisZ.y * temp2.z, basisX.z * temp2.x + basisY.z * temp2.y + basisZ.z * temp2.z); temp2.Div(temp2.Length()); //temp2.Set(temp3); temp.Set(pos).Add(0, 0, -height); /*******************************************************************************/ /* frameIndex = temp.ToXYZ(); * XYZ deltaSign = new XYZ(Math.Sign(temp2.x),Math.Sign(temp2.y),Math.Sign(temp2.z)); * int nextDir = 0; * XYZ_d maxNumOfDelta = new XYZ_d(frameLength).Mul(deltaSign).Div(temp2); * XYZ_d target = new XYZ_d(halfFrameLength); * target.Mul(deltaSign);//delta벡터 방향으로 이동시 접촉가능한 경계면들 구하기. * target.Div(temp2); */ //XYZ gap = new XYZ(frameIndex); //color.Set(2,2,2); //byte code = 0; for (int k = 0; k < height * 1.5f; k++) { temp.Add(temp2); frameIndex = temp.ToXYZ(); /* if (target.x < target.y) * if(target.x < target.z) nextDir = 0; * else nextDir = 2; * else * if(target.y < target.z) nextDir = 1; * else nextDir = 2; */ //target.element[nextDir] += maxNumOfDelta.element[nextDir]; //frameIndex.element[nextDir] += deltaSign.element[nextDir]; ConvertToInfinity(frameIndex); if (isFrameEnabled(frameIndex)) { AddColor(frameIndex, color2); break; } else { AddColor(frameIndex, color); } //SetBlock(frameIndex,code); //gap.Set(frameIndex); //Console.WriteLine(nextDir); } } } } }