public static void CheckMatching(V2l v1, V2l v2) { if (v1 != v2) { throw new Exception("mismatch"); } }
/// <summary> /// Perform the supplied action on grid elements that are separated /// by a supplied step size. Only near the borders, the separation /// may be smaller. The (possibly) smaller border separation is /// distributed to all four borders. /// </summary> public void SampleRegular(V2l step, Action <long, long, double, double> sample) { V2l regularLast = (m_last / step) * step; V2l offset = (m_last - regularLast) / 2; regularLast += offset; if (offset.Y > 0) { if (offset.X > 0) { sample(0, 0, m_region.Min.X, m_region.Min.Y); } for (long xi = offset.X; xi <= regularLast.X; xi += step.X) { sample(xi, 0, m_region.Min.X + xi * m_delta.X, m_region.Min.Y); } if (regularLast.X < m_last.X) { sample(m_last.X, 0, m_region.Max.X, m_region.Min.Y); } } for (long yi = offset.Y; yi <= regularLast.Y; yi += step.Y) { double y = m_region.Min.Y + yi * m_delta.Y; if (offset.X > 0) { sample(0, yi, m_region.Min.X, y); } for (long xi = offset.X; xi <= regularLast.X; xi += step.X) { sample(xi, yi, m_region.Min.X + xi * m_delta.X, y); } if (regularLast.X < m_last.X) { sample(m_last.X, yi, m_region.Max.X, y); } } if (regularLast.Y < m_last.Y) { if (offset.X > 0) { sample(0, m_last.Y, m_region.Min.X, m_region.Max.Y); } for (long xi = offset.X; xi <= regularLast.X; xi += step.X) { sample(xi, m_last.Y, m_region.Min.X + xi * m_delta.X, m_region.Max.Y); } if (regularLast.X < m_last.X) { sample(m_last.X, m_last.Y, m_region.Max.X, m_region.Max.Y); } } }
/// <summary> /// NOTE: this indexer has reversed order of coordinates with respect to /// the default indexer!!! /// </summary> public double this[V2l v] { get { return /*# if (ftype != "double") { */ ((double)/*# } */ this[(int)v.Y, (int)v.X]); } set { this[(int)v.Y, (int)v.X] = /*# if (ftype != "double") { */ (__ftype__)/*# } */ value; } }
public void ForeachY(int x, Action <long, V2l> action) { long index = GetIndex(x, 0); V2l vec = new V2l(x, 0); for (vec.Y = 0; vec.Y <= x; vec.Y++) { action(index, vec); index += (m_size - vec.Y - 1); } }
/// <summary> /// Calculates the sum for a given set of V2ls. /// </summary> public static V2l Sum(this V2l[] vectors) { V2l sum = V2l.Zero; for (var i = 0; i < vectors.Length; i++) { sum += vectors[i]; } return(sum); }
public void ForeachX(int y, Action <long, V2l> action) { long index = GetIndex(y, y); V2l vec = new V2l(y, y); for (vec.X = y; vec.X < m_size; vec.X++) { action(index, vec); index++; } }
/// <summary> /// Calculates the sum for a given set of V2ls. /// </summary> public static V2l Sum(this IEnumerable <V2l> vectors) { V2l sum = V2l.Zero; foreach (var e in vectors) { sum += e; } return(sum); }
/// <summary> /// Access a single pixel of an image volume as a Vec. Note that this /// involves an indexing operation with two index multiplications. /// </summary> public static Vec <T> VecPixel <T>( this Volume <T> vol, V2l position) { #if DEBUG if (vol.Info.Delta.Z != 1) { throw new ArgumentException(); } #endif return(new Vec <T>(vol.Data, vol.Info.Origin + position.X * vol.Info.Delta.X + position.Y * vol.Info.Delta.Y, vol.Info.Size.Z)); }
public void ForeachCoord(Action <long, long> action) { V2l current = V2l.Zero; for (long i = 0; i < m_data.Length; i++) { action(current.X, current.Y); current.X++; if (current.X >= m_size) { current.Y++; current.X = current.Y; } } }
public void SetByCoord(Func <long, long, T> setter) { V2l current = V2l.Zero; for (long i = 0; i < m_data.Length; i++) { m_data[i] = setter(current.X, current.Y); current.X++; if (current.X >= m_size) { current.Y++; current.X = current.Y; } } }
public void Sample(V2l count, Action <long, long, double, double> sample) { V2d step = (V2d)m_last / (V2d)count; double yd = 0.5; for (int yi = 0; yi <= m_last.Y; yd += step.Y, yi = (int)yd) { double y = m_region.Min.Y + yi * m_delta.Y; double xd = 0.5; for (int xi = 0; xi <= m_last.X; xd += step.X, xi = (int)xd) { double x = m_region.Min.X + xi * m_delta.X; sample(xi, yi, x, y); } } }
public void Sample(V2l count, Action <long, long, long, long, double, double, double, double> region) { V2d step = (V2d)m_last / (V2d)count; double y = m_region.Min.Y; double yd = 0.5 + step.Y; for (int yi = 0, nyi = (int)yd; yi < m_last.Y; yd += step.Y, yi = nyi, nyi = (int)yd) { double ny = m_region.Min.Y + nyi * m_delta.Y; double x = m_region.Min.X; double xd = 0.5 + step.X; for (int xi = 0, nxi = (int)xd; xi < m_last.X; xd += step.X, xi = nxi, nxi = (int)xd) { double nx = m_region.Min.X + nxi * m_delta.X; region(xi, nxi, yi, nyi, x, nx, y, ny); x = nx; } y = ny; } }
/// <summary> /// Create a valid image matrix, with stride appropriate for the /// given size. Note that this is just the same as a normal matrix. /// </summary> public static Matrix <T> CreateImageMatrix <T>(this V2l size) { return(new Matrix <T>(size)); }
/// <summary> /// Convert from normalized image position [0,1][0,1] to already rounded pixel-center position. /// </summary> /// <param name="pos">The pixel location defined in pixel space: (0,0)=center of upper left pixel, (w-1,h-1)=center of lower right pixel.</param> /// <param name="imgSizeInPixel">The size of the image (as V2d to safe lots of conversions).</param> /// <returns>A normalized image position in [0, imgSizeInPixel.X-1][0, imgSizeInPixel.Y-1].</returns> public static V2l NormalizedImagePosToPixelCenterRound(V2d pos, V2l imgSizeInPixel) => (V2l)NormalizedImagePosToPixelCenter(pos, imgSizeInPixel).Copy(v => Round(v));
public T this[V2l vec] { get { return(m_data[GetIndex(vec.X, vec.Y)]); } set { m_data[GetIndex(vec.X, vec.Y)] = value; } }
/// <summary> /// Convert from normalized image position [0,1][0,1] to pixel-center position /// (The inverse of toNormalizedImgPos.) /// </summary> /// <param name="pos">The pixel location defined in pixel space: (0,0)=center of upper left pixel, (w-1,h-1)=center of lower right pixel.</param> /// <param name="imgSizeInPixel">The size of the image (as V2d to safe lots of conversions).</param> /// <returns>A image position in [-0.5,imgSizeInPixel.X-0.5][-0.5,imgSizeInPixel.Y-0.5].</returns> public static V2d NormalizedImagePosToPixelCenter(V2d pos, V2l imgSizeInPixel) { return(new V2d(pos.X * imgSizeInPixel.X, pos.Y * imgSizeInPixel.Y) - V2dHalf); }
/// <summary> /// Cell with min corner at index*2^exponent and dimension 2^exponent. /// </summary> public Cell2d(V2l index, int exponent) : this(index.X, index.Y, exponent) { }
public static void CheckMatching(V2l v1, V2l v2, V2l v3, V2l v4) { CheckMatching(v1, v2); CheckMatching(v1, v3); CheckMatching(v1, v4); }
public Border2l(V2l min, V2l max) { Min = min; Max = max; }
/// <summary> /// Perform the supplied action on grid regions of a supplied step /// size. Only near the borders, the regions may be smaller. The /// (possibly) smaller border region size is distributed to all four /// borders. /// </summary> public void SampleRegular(V2l step, Action <long, long, long, long, double, double, double, double> region) { V2l regularLast = (m_last / step) * step; V2l offset = (m_last - regularLast) / 2; regularLast += offset; if (offset.Y > 0) { double maxY = m_region.Min.Y + offset.Y * m_delta.Y; if (offset.X > 0) { region(0, offset.X, 0, offset.Y, m_region.Min.X, m_region.Min.X + offset.X * m_delta.X, m_region.Min.Y, maxY); } for (long xi = offset.X, nxi = xi + step.X; xi < regularLast.X; xi = nxi, nxi += step.X) { region(xi, nxi, 0, offset.Y, m_region.Min.X + xi * m_delta.X, m_region.Min.X + nxi * m_delta.X, m_region.Min.Y, maxY); } if (regularLast.X < m_last.X) { region(regularLast.X, m_last.X, 0, offset.Y, m_region.Min.X + regularLast.X * m_delta.X, m_region.Min.X + m_last.X * m_delta.X, m_region.Min.Y, maxY); } } for (long yi = offset.Y, nyi = yi + step.Y; yi < regularLast.Y; yi = nyi, nyi += step.Y) { double minY = m_region.Min.Y + yi * m_delta.Y; double maxY = minY + m_delta.Y; if (offset.X > 0) { region(0, offset.X, yi, nyi, m_region.Min.X, m_region.Min.X + offset.X * m_delta.X, minY, maxY); } for (long xi = offset.X, nxi = xi + step.X; xi < regularLast.X; xi = nxi, nxi += step.X) { region(xi, nxi, yi, nyi, m_region.Min.X + xi * m_delta.X, m_region.Min.X + nxi * m_delta.X, minY, maxY); } if (regularLast.X < m_last.X) { region(regularLast.X, m_last.X, yi, nyi, m_region.Min.X + regularLast.X * m_delta.X, m_region.Min.X + m_last.X * m_delta.X, minY, maxY); } } if (regularLast.Y < m_last.Y) { double minY = m_region.Min.Y + regularLast.Y * m_delta.Y; if (offset.X > 0) { region(0, offset.X, regularLast.Y, m_last.Y, m_region.Min.X, m_region.Min.X + offset.X * m_delta.X, minY, m_region.Max.Y); } for (long xi = offset.X, nxi = xi + step.X; xi < regularLast.X; xi = nxi, nxi += step.X) { region(xi, xi + step.X, regularLast.Y, m_last.Y, m_region.Min.X + xi * m_delta.X, m_region.Min.X + nxi * m_delta.X, minY, m_region.Max.Y); } if (regularLast.X < m_last.X) { region(regularLast.X, m_last.X, regularLast.Y, m_last.Y, m_region.Min.X + regularLast.X * m_delta.X, m_region.Min.X + m_last.X * m_delta.X, minY, m_region.Max.Y); } } }
/// <summary> /// Return a sub image volume beginning at the supplied pixel /// coordinate with the supplied size in pixels. The coordinates /// of the sub image volume start at 0, 0, 0. /// </summary> public static Volume <T> SubImage <T>( this Volume <T> vol, V2l begin, V2l size) { return(vol.SubVolume(new V3l(begin.X, begin.Y, vol.FZ), new V3l(size.X, size.Y, vol.SZ))); }
public object GetValue(V2l v) { return((object)this[(int)(v.X), (int)(v.Y)]); }
/// <summary> /// Convert from normalized image position [0,1][0,1] to already rounded pixel-center position. /// </summary> /// <param name="pos">The pixel location defined in pixel space: (0,0)=center of upper left pixel, (w-1,h-1)=center of lower right pixel.</param> /// <param name="imgSizeInPixel">The size of the image (as V2d to safe lots of conversions).</param> /// <returns>A normalized image position in [0, imgSizeInPixel.X-1][0, imgSizeInPixel.Y-1].</returns> public static V2l NormalizedImagePosToPixelCenterRound(V2d pos, V2l imgSizeInPixel) { return((V2l)NormalizedImagePosToPixelCenter(pos, imgSizeInPixel).Copy(v => System.Math.Round(v))); }
public void SetValue(object value, V2l v) { this[(int)(v.X), (int)(v.Y)] = (__ftype__)value; }
/// <summary> /// Iterates along Bresenham discrete line raster from p0 to p1. /// Yields each integer position V2l. /// </summary> public static IEnumerable <V2l> BresenhamLineIterator(V2l p0, V2l p1) { long x0 = p0.X, y0 = p0.Y, x1 = p1.X, y1 = p1.Y; long dx, dy; long incx, incy; long balance; if (x1 >= x0) { dx = x1 - x0; incx = 1; } else { dx = x0 - x1; incx = -1; } if (y1 >= y0) { dy = y1 - y0; incy = 1; } else { dy = y0 - y1; incy = -1; } if (dx >= dy) { dy <<= 1; balance = dy - dx; dx <<= 1; while (x0 != x1) { yield return(new V2l(x0, y0)); if (balance >= 0) { y0 += incy; balance -= dx; } balance += dy; x0 += incx; } yield return(new V2l(x0, y0)); } else { dx <<= 1; balance = dx - dy; dy <<= 1; while (y0 != y1) { yield return(new V2l(x0, y0)); if (balance >= 0) { x0 += incx; balance -= dy; } balance += dx; y0 += incy; } yield return(new V2l(x0, y0)); } }
public SampleGrid2d(V2l gridSize, Box2d region) { m_last = gridSize - new V2l(1, 1); m_region = region; m_delta = region.Size / (V2d)m_last; }