public Cell GetCell(int X, int Y, int Z) { // Формат именования вершин в кубе. // На первом месте либо T (top, верхняя грань), либо B (bottom, нижняя грань) // далее N (north, северная, условный верх) либо S (south, южная, условный низ) грань // и завершается W( west, западная, условное лево) либо E (east, восточное, условное право). //Таким образом, трехбуквенным кодом обозначаются восемь вершин одной ячейки. // Это распространенный подход. Cell CELL = new Cell(); // Отметки глубин EclipseProject Project = Manager.ActiveProject; // Синоним, для облегчения читаемости CELL.TNW.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + 2 * X + 0]; CELL.TNE.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + 2 * X + 1]; CELL.TSW.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + 2 * X + Project.NX * 2 + 0]; CELL.TSE.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + 2 * X + Project.NX * 2 + 1]; CELL.BNW.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + Project.NX * Project.NY * 4 + 2 * X + 0]; CELL.BNE.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + Project.NX * Project.NY * 4 + 2 * X + 1]; CELL.BSW.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + Project.NX * Project.NY * 4 + 2 * X + Project.NX * 2 + 0]; CELL.BSE.Z = Project.ZCORN[Z * Project.NX * Project.NY * 8 + Y * Project.NX * 4 + Project.NX * Project.NY * 4 + 2 * X + Project.NX * 2 + 1]; // Направляющая линия от TNW до BNW Vector3 TOP, BTM; TOP.X = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 0]; TOP.Y = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 1]; TOP.Z = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 2]; BTM.X = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 3 + 0]; BTM.Y = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 3 + 1]; BTM.Z = Project.COORD[(X + (Project.NX + 1) * Y) * 6 + 3 + 2]; float FRAC = 0; if (BTM.Z == TOP.Z) // нет наклона направляющей линии, значит координаты равны { CELL.TNW.X = TOP.X; CELL.TNW.Y = TOP.Y; CELL.BNW.X = BTM.X; CELL.BNW.Y = BTM.Y; } else { FRAC = (CELL.TNW.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.TNW.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.TNW.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); FRAC = (CELL.BNW.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.BNW.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.BNW.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); } // Направляющая линия от TNE до BNE TOP.X = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 0]; TOP.Y = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 1]; TOP.Z = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 2]; BTM.X = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 3 + 0]; BTM.Y = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 3 + 1]; BTM.Z = Project.COORD[((X + 1) + (Project.NX + 1) * Y) * 6 + 3 + 2]; if (BTM.Z == TOP.Z) // нет наклона направляющей линии, значит координаты равны { CELL.TNE.X = TOP.X; CELL.TNE.Y = TOP.Y; CELL.BNE.X = BTM.X; CELL.BNE.Y = BTM.Y; } else { FRAC = (CELL.TNE.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.TNE.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.TNE.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); FRAC = (CELL.BNE.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.BNE.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.BNE.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); } // Направляющая линия от TSE до BSE TOP.X = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 0]; TOP.Y = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 1]; TOP.Z = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 2]; BTM.X = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 0]; BTM.Y = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 1]; BTM.Z = Project.COORD[((X + 1) + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 2]; if (BTM.Z == TOP.Z) // нет наклона направляющей линии, значит координаты равны { CELL.TSE.X = TOP.X; CELL.TSE.Y = TOP.Y; CELL.BSE.X = BTM.X; CELL.BSE.Y = BTM.Y; } else { FRAC = (CELL.TSE.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.TSE.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.TSE.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); FRAC = (CELL.BSE.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.BSE.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.BSE.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); } // Направляющая линия от TSW до BSW TOP.X = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 0]; TOP.Y = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 1]; TOP.Z = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 2]; BTM.X = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 0]; BTM.Y = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 1]; BTM.Z = Project.COORD[(X + (Project.NX + 1) * (Y + 1)) * 6 + 3 + 2]; if (BTM.Z == TOP.Z) // нет наклона направляющей линии, значит координаты равны { CELL.TSW.X = TOP.X; CELL.TSW.Y = TOP.Y; CELL.BSW.X = BTM.X; CELL.BSW.Y = BTM.Y; } else { FRAC = (CELL.TSW.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.TSW.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.TSW.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); FRAC = (CELL.BSW.Z - TOP.Z) / (BTM.Z - TOP.Z); CELL.BSW.X = TOP.X + FRAC * (BTM.X - TOP.X); CELL.BSW.Y = TOP.Y + FRAC * (BTM.Y - TOP.Y); } return CELL; }
public void MouseClick(MouseEventArgs e) { if (IsActivated2D == false) return; float XT, YT = 0; float DX, DY; float value; // Тест на выбранную ячейку, работает не очень хорошо if (e.Button == System.Windows.Forms.MouseButtons.Left) { XS = -1; YS = -1; ZS = -1; int[] viewport = new int[4]; GL.GetInteger(GetPName.Viewport, viewport); byte[] pixel = null; IntPtr p = new IntPtr(); GL.ReadPixels(e.X, viewport[3] - e.Y, 1, 1, PixelFormat.Rgb, PixelType.UnsignedByte, ref p); pixel = BitConverter.GetBytes(p.ToInt32()); Color COLOR = new Color(); Cell CELL = new Cell(); int[] SIGN = new int[4]; if (SelectedViewMode == ViewMode.X) { XT = (e.X - 0.5f * Width) / scale + xmin + 0.5f * (xmax - xmin) - shiftX - shiftEndX + shiftStartX; YT = (e.Y - 0.5f * Height) / (scale * scalez) + ymin + 0.5f * (ymax - ymin) + shiftY - shiftEndY + shiftStartY; DX = (xmax - xmin) / NY; DY = (ymax - ymin) / NZ; for (int Z = 0; Z < NZ; ++Z) for (int Y = 0; Y < NY; ++Y) { value = Presenter.GetGridValue(XA, Y, Z); if (!float.IsNaN(value)) { COLOR = colorizer.ColorByValue(value); if (COLOR.R == pixel[0]) if (COLOR.G == pixel[1]) if (COLOR.B == pixel[2]) { CELL = Presenter.GetCell(XA, Y, Z); SIGN[0] = Math.Sign(CELL.TSE.Y * (1 - StretchFactor) + (xmin + DX * Y + DX) * StretchFactor - XT); SIGN[1] = Math.Sign(CELL.BSE.Y * (1 - StretchFactor) + (xmin + DX * Y + DX) * StretchFactor - XT); SIGN[2] = Math.Sign(CELL.BNE.Y * (1 - StretchFactor) + (xmin + DX * Y) * StretchFactor - XT); SIGN[3] = Math.Sign(CELL.TNE.Y * (1 - StretchFactor) + (xmin + DX * Y) * StretchFactor - XT); if (Math.Abs(SIGN.Sum()) != 4) { SIGN[0] = Math.Sign(CELL.TSE.Z * (1 - StretchFactor) + (ymin + DY * Z) * StretchFactor - YT); SIGN[1] = Math.Sign(CELL.BSE.Z * (1 - StretchFactor) + (ymin + DY * Z + DY) * StretchFactor - YT); SIGN[2] = Math.Sign(CELL.BNE.Z * (1 - StretchFactor) + (ymin + DY * Z + DY) * StretchFactor - YT); SIGN[3] = Math.Sign(CELL.TNE.Z * (1 - StretchFactor) + (ymin + DY * Z) * StretchFactor - YT); if (Math.Abs(SIGN.Sum()) != 4) { ZS = Z; YS = Y; break; } } } } } } if (SelectedViewMode == ViewMode.Y) { XT = (e.X - 0.5f * Width) / scale + xmin + 0.5f * (xmax - xmin) - shiftX - shiftEndX + shiftStartX; YT = (e.Y - 0.5f * Height) / (scale * scalez) + ymin + 0.5f * (ymax - ymin) + shiftY - shiftEndY + shiftStartY; DX = (xmax - xmin) / NX; DY = (ymax - ymin) / NZ; for (int Z = 0; Z < NZ; ++Z) for (int X = 0; X < NX; ++X) { value = Presenter.GetGridValue(X, YA, Z); if (!float.IsNaN(value)) { COLOR = colorizer.ColorByValue(value); if (COLOR.R == pixel[0]) if (COLOR.G == pixel[1]) if (COLOR.B == pixel[2]) { CELL = Presenter.GetCell(X, YA, Z); SIGN[0] = Math.Sign(CELL.TSW.X * (1 - StretchFactor) + (xmin + DX * X) * StretchFactor - XT); SIGN[1] = Math.Sign(CELL.TSE.X * (1 - StretchFactor) + (xmin + DX * X + DX) * StretchFactor - XT); SIGN[2] = Math.Sign(CELL.BSE.X * (1 - StretchFactor) + (xmin + DX * X + DX) * StretchFactor - XT); SIGN[3] = Math.Sign(CELL.BSW.X * (1 - StretchFactor) + (xmin + DX * X) * StretchFactor - XT); if (Math.Abs(SIGN.Sum()) != 4) { SIGN[0] = Math.Sign(CELL.TSW.Z * (1 - StretchFactor) + (ymin + DY * Z) * StretchFactor - YT); SIGN[1] = Math.Sign(CELL.TSE.Z * (1 - StretchFactor) + (ymin + DY * Z) * StretchFactor - YT); SIGN[2] = Math.Sign(CELL.BSE.Z * (1 - StretchFactor) + (ymin + DY * Z + DY) * StretchFactor - YT); SIGN[3] = Math.Sign(CELL.BSW.Z * (1 - StretchFactor) + (ymin + DY * Z + DY) * StretchFactor - YT); if (Math.Abs(SIGN.Sum()) != 4) { ZS = Z; XS = X; break; } } } } } } if (SelectedViewMode == ViewMode.Z) { XT = (e.X - 0.5f * Width) / scale + xmin + 0.5f * (xmax - xmin) - shiftX - shiftEndX + shiftStartX; YT = (e.Y - 0.5f * Height) / scale + ymin + 0.5f * (ymax - ymin) + shiftY - shiftEndY + shiftStartY; for (int X = 0; X < NX; ++X) for (int Y = 0; Y < NY; ++Y) { value = Presenter.GetGridValue(X, Y, ZA); if (!float.IsNaN(value)) { COLOR = colorizer.ColorByValue(value); if (COLOR.R == pixel[0]) if (COLOR.G == pixel[1]) if (COLOR.B == pixel[2]) { CELL = Presenter.GetCell(X, Y, ZA); SIGN[0] = Math.Sign(CELL.TNW.X - XT); SIGN[1] = Math.Sign(CELL.TNE.X - XT); SIGN[2] = Math.Sign(CELL.TSW.X - XT); SIGN[3] = Math.Sign(CELL.TSE.X - XT); if (Math.Abs(SIGN.Sum()) != 4) { SIGN[0] = Math.Sign(CELL.TNW.Y - YT); SIGN[1] = Math.Sign(CELL.TNE.Y - YT); SIGN[2] = Math.Sign(CELL.TSW.Y - YT); SIGN[3] = Math.Sign(CELL.TSE.Y - YT); if (Math.Abs(SIGN.Sum()) != 4) { XS = X; YS = Y; break; } } } } } } } }