public XYZ_d Mul(XYZ_d d) { return(Mul(d.x, d.y, d.z)); }
public XYZ_d Add(XYZ_d d) { return(Add(d.x, d.y, d.z)); }
public XYZ_d Sub(XYZ_d d) { return(Sub(d.x, d.y, d.z)); }
public Pixel(XYZ_d p, int lev) { Position = p; level = lev; }
public XYZ_d(XYZ_d d) : this(d.x, d.y, d.z) { }
public XYZ_d Set(XYZ_d d) { return(Set(d.x, d.y, d.z)); }
public double Distance(XYZ_d d) { return(Math.Sqrt(Math.Pow(x - d.x, 2) + Math.Pow(y - d.y, 2) + Math.Pow(z - d.z, 2))); }
public Machine(XYZ_d p, Modifier m) { Position = p; modifier = m; }
public XYZ_d Div(XYZ_d d) { return(Div(d.x, d.y, d.z)); }
public LightSphere(XYZ_d p, int r, int ra, int l) : base(p, new XYZ(ra * 2)) { range = ra; radius = r; maxLevel = l; MakeShape(); }
public Cube(XYZ_d p, XYZ s) : base(p, s) { MakeShape(); }
public Cylinder(XYZ_d p, int r, int h) : base(p, new XYZ(r * 2, h, r * 2)) { radius = r; heigh = h; MakeShape(); }
public Sphere(XYZ_d p, int r) : base(p, new XYZ(r * 2)) { radius = r; MakeShape(); }
void Spin_matrix_z(double x, double y, double z, double sin, double cos, XYZ_d position) { position.x = x * cos + y * sin; position.y = y * cos + x * sin * -1; }
//void MakeImage() //{ // XYZ framePos = new XYZ(); // XYZ_d lpos = new XYZ_d(); // if (board[camPoint.x, camPoint.z] != null && !isTargetSet) // { // board[k, i].Add(position); // world.GetFrameIndex(board[k, i], framePos); // deleteFrameIndex.Set(framePos); // // addFrameIndex.Set(frameIndex).Sub(nextFrameIndexDelta); // isTargetSet = true; // } // for (int k = 0; k < camSize.z; k++) // { // for(int i = 0; i < camSize.x; i++) // { // if (board[k, i] != null) // { // board[k, i].Add(position); // world.GetFrameIndex(board[k, i], framePos); // world.ConvertToFramePos(lpos.Set(board[k, i]), framePos); // Block block = world.GetBlock(frameIndex); // if (framePos.Equal(deleteFrameIndex))//쳐다보는 블록면 강조 // { // XYZ_b inv_color = new XYZ_b(255).Sub(block.color); // XYZ vector = new XYZ(addFrameIndex).Sub(deleteFrameIndex); // if (vector.x != 0 && lpos.x * vector.x > world.frameLength / 2 - 1) // { // viewer.Draw(i, k, inv_color); // break; // } // else if (vector.y != 0 && lpos.y * vector.y > world.frameLength / 2 - 1) // { // viewer.Draw(i, k, inv_color); // break; // } // else if (vector.z != 0 && lpos.z * vector.z > world.frameLength / 2 - 1) // { // viewer.Draw(i, k, inv_color); // break; // } // } // if (gridEnabled && block.code != 14)// 경계선표시. // { // 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; // if (Xaxis && Yaxis) { viewer.Draw(i, k, inv_color); break; } // if (Yaxis && Zaxis) { viewer.Draw(i, k, inv_color); break; } // if (Zaxis && Xaxis) { viewer.Draw(i, k, inv_color); break; } // } // } // } // } //} void Spin_matrix_x(double x, double y, double z, double sin, double cos, XYZ_d position) { position.y = y * cos + z * sin; position.z = z * cos + y * sin * -1; position.x = x; }
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) => for (int k = 0; k < camSize.z; k++) { //Parallel.For(0,camSize.x,(int i) => for (int i = 0; i < camSize.x; i++) { XYZ_b color = new XYZ_b(); Block block; 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) { break; } world.ConvertToFramePos(lpos.Set(index), frameIndex); // index를 frameIndex에 해당하는 블록의 로컬포지션으로 변환. if (world.IsExistPixelInFrame(frameIndex)) { block = world.GetBlock(frameIndex); board[i, k] = index; if (i == camPoint.x && k == camPoint.z && !isTargetSet) { deleteFrameIndex.Set(frameIndex); addFrameIndex.Set(frameIndex).Sub(nextFrameIndexDelta); isTargetSet = true; } XYZ_b inv_color = new XYZ_b(255).Sub(block.color); if (frameIndex.Equal(deleteFrameIndex))//쳐다보는 블록면 강조 { XYZ vector = new XYZ(addFrameIndex).Sub(deleteFrameIndex); if (vector.x != 0 && lpos.x * vector.x > world.frameLength / 2 - 1) { viewer.Draw(i, k, inv_color); break; } else if (vector.y != 0 && lpos.y * vector.y > world.frameLength / 2 - 1) { viewer.Draw(i, k, inv_color); break; } else if (vector.z != 0 && lpos.z * vector.z > world.frameLength / 2 - 1) { viewer.Draw(i, k, inv_color); break; } } if (gridEnabled && block.code != 14) // 경계선표시. { 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; if (Xaxis && Yaxis) { viewer.Draw(i, k, inv_color); break; } if (Yaxis && Zaxis) { viewer.Draw(i, k, inv_color); break; } if (Zaxis && Xaxis) { viewer.Draw(i, k, inv_color); break; } } if (block.code == 14) // 거울만나면 반사. { color.Set(block.color); 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 (block.code == 15) // 유리만나면 살짝 하얘지고 계속 진행. { color.Add(10); } else { color.Add(block.color); viewer.Draw(i, k, color); 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]); for (int i = camPoint.z - 3; i < camPoint.z + 3; i++) { for (int j = camPoint.x - 3; j < camPoint.x + 3; j++) { if (Math.Pow(i - camPoint.z, 2) + Math.Pow(j - camPoint.x, 2) < 8 && Math.Pow(i - camPoint.z, 2) + Math.Pow(j - camPoint.x, 2) > 4) { viewer.Draw(j, i, new XYZ_b(255)); } } } }