I know so many questions have been already asked based on this topic and still i am unable to generate tiles in isometric view.
please check the below code and its out put
private void picIsometricBox_Paint(object sender, PaintEventArgs e)
{
try
{
int paddingTop = sdpaddingTop.Value * -80;
int paddingleft = sdpaddingLeft.Value * 40;
int rotateangle = sbRotate.Value * 5;
int noofCells = 9;
int cellsize = 60;
int x = 0;
for (int j = 1; j <= noofCells; j++)
{
for (int i = 1; i <= noofCells; i++)
{
var ep = (x % 2) == 0 ? Brushes.White : Brushes.Black;
int xv = (j * cellsize + paddingleft);
int yv = (i * cellsize) + paddingTop;
int xxv = (i * cellsize) + paddingleft;
int yyv = cellsize + paddingTop;
e.Graphics.RotateTransform(rotateangle);
e.Graphics.FillRectangle(ep, xv, yv, cellsize, cellsize);
e.Graphics.FillRectangle(ep, xxv, yyv, cellsize, cellsize);
e.Graphics.ResetTransform();
x++;
}
}
}
catch (Exception ex)
{
}
}
output is rendered in picture box:
I am not sure how to generate tiles like below
Related
Well, my question is pretty simple to understand, I'm trying to create a grid of chunks but on each step, I want to double the distance of a chunk.
Then, this is the code I have:
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class DrawLoDTest : MonoBehaviour
{
private List<Vector3> initialChunks;
public int chunkSize = 16;
public int lodLevels = 2;
public int width = 16;
public int height = 16;
private Color[] colorList;
// Start is called before the first frame update
private void Start()
{
}
// Update is called once per frame
private void Update()
{
}
private void Init()
{
if (initialChunks != null && initialChunks.Count > 0)
return;
colorList = new[] { Color.blue, Color.green, Color.yellow, Color.cyan, Color.magenta, Color.grey };
Debug.Log("Init test!");
initialChunks = new List<Vector3>(16 * 16);
for (var i = 0; i < width * height; i++)
{
var x = i % width;
var y = i / width;
initialChunks.Add(new Vector3(x * chunkSize - width * chunkSize / 2, 0, y * chunkSize - height * chunkSize / 2));
}
//Debug.Log(string.Join(Environment.NewLine, initialChunks.Select(v => v.ToString())));
}
private void OnDrawGizmos()
{
Init();
Gizmos.color = Color.red;
foreach (var chunk in initialChunks)
{
Gizmos.DrawWireCube(chunk, Vector3.one * chunkSize);
}
var ww = 0;
var ww2 = 0;
var sum = 0;
var halfChunkSize = chunkSize / 2;
var halfWidth = width * halfChunkSize;
var halfHeight = height * halfChunkSize;
for (var i = 1; i <= lodLevels; i++)
{
if (ww > 0)
++ww2;
var pow = (int)Mathf.Pow(2, i);
var w = width / pow;
var h = height / pow;
Gizmos.color = colorList[i - 1];
var oddSum = ww * chunkSize * pow;
for (var x = -1 - ww2; x <= w + ww2; x++)
{
for (var n = 0; n <= 1; n++)
{
var sign = n == 0 ? -1 : 1;
var chunk = new Vector3(
halfWidth - x * chunkSize * pow - halfChunkSize,
0,
halfHeight * sign - halfChunkSize - chunkSize * 2 * sign + oddSum * sign + sum * sign);
chunk.x -= pow * halfChunkSize;
for (var j = i + 1; j >= i; j--)
{
chunk.z += chunkSize * (int)Mathf.Pow(2, j) / 2 * sign;
}
Gizmos.DrawWireCube(chunk, Vector3.one * chunkSize * pow);
}
}
// TODO
if ((w + ww2 * 2 + 2) / 2 % 2 != 0)
{
Debug.Log($"[{i}, {ww}, {ww2}] W: {w} + {ww2} * 2 = {w + ww2 * 2} + 2 = {w + ww2 * 2 + 2} / 2 = {(w + ww2 * 2 + 2) / 2}");
if (ww == 0)
{
--i;
++ww;
}
else
{
ww = 0;
sum += oddSum;
}
}
else
{
if (ww2 > 0)
ww2 = 0;
}
}
}
}
A little bit of explanation:
First, I load a 16x16 chunk grid (initialChunks).
Then, I start a loop foreach lod level (I'm testing it for 6 levels).
Then, foreach axis I iterate its position.
Then, in a nested loop foreach axis I give a sign (a loop for 0 to 1, that converts into -1 and 1 for the sign).
Then, and this is the more complex thing, if the following row/column has an odd number of elements then I try to match the current row/column by doubling it, in that way non of the following corner will be half of the previous one, like the image below:
I have two main problems:
For some reason, sum and oddSum variables has the wrong input.
At certain levels, (for i >= 5) the logic is broken.
As the title said, I'm compressing an image (inputed as a Texture2D) by dividing the image into blocks and taking the average r, g, and b value.
Image:
But the result is mostly gray-ish color with a diagonal strip of other colors in the middle:
This is the code for compression:
private void ASCIIConvert()
{
texWidth = tex.width; texHeight = tex.height;
int blockHeight = Mathf.FloorToInt((float)texHeight / neededHeight);
int blockWidth = Mathf.FloorToInt((float)texWidth / neededWidth);
int maxHeight = blockHeight * neededHeight;
int maxWidth = blockWidth * neededWidth;
int numBlockHeight = maxHeight/blockHeight;
int numBlockWidth = maxWidth/blockWidth;
tex2 = new Texture2D(numBlockWidth, numBlockHeight);
for (int idx = 0; idx < maxHeight; idx += blockHeight)
{
int curBlockHeight = Mathf.FloorToInt((float) idx / blockHeight);
for (int j = 0; j < maxWidth; j += blockWidth)
{
float sumr = 0, sumg = 0, sumb = 0;
int curBlockWidth = Mathf.FloorToInt((float) idx / blockWidth);
for (int m = idx * blockHeight; m < idx * blockHeight + blockHeight; m++)
{
for (int n = j * blockWidth; n < j * blockWidth + blockWidth; n++)
{
sumr += tex.GetPixel(n,m).r;
sumg += tex.GetPixel(n,m).g;
sumb += tex.GetPixel(n,m).b;
}
}
sumr /= (blockWidth * blockHeight);
sumg /= (blockWidth * blockHeight);
sumb /= (blockWidth * blockHeight);
tex2.SetPixel(curBlockWidth, curBlockHeight, new Color(sumr, sumg, sumb, 1f));
}
}
tex2.Apply();
//standard
newSprite = Sprite.Create(tex2, new Rect(0.0f, 0.0f, tex2.width, tex2.height), new Vector2(0.5f, 0.5f), 100.0f);
imgContainer.GetComponent<SpriteRenderer>().sprite = newSprite;
}
neededWidth and neededHeight are length and width of the wanted compressed texture. Any idea where the compression may have gone wrong?
I am trying to implement Hough Line Transform.
Input. I am using the following image as input. This single line is expected to produce only one intersection of sine waves in the output.
Desired behavior. my source code is expected to produce the following output as it was generated by the sample application of AForge framework.
Here, we can see:
the dimension of the output is identical to the input image.
the intersection of sine waves are seen at almost at the center.
the intersection pattern of waves is very small and simple.
Present behavior. My source code is producing the following output which is different than that of the output generated by AForge.
the intersection is not at the center.
the wave patterns are also different.
Why is my code producing a different output?
.
Source Code
I have written the following code myself. The following is a Minimal, Complete, and Verifiable source code.
public class HoughMap
{
public int[,] houghMap { get; private set; }
public int[,] image { get; set; }
public void Compute()
{
if (image != null)
{
// get source image size
int inWidth = image.GetLength(0);
int inHeight = image.GetLength(1);
int inWidthHalf = inWidth / 2;
int inHeightHalf = inHeight / 2;
int outWidth = (int)Math.Sqrt(inWidth * inWidth + inHeight * inHeight);
int outHeight = 180;
int outHeightHalf = outHeight / 2;
houghMap = new int[outWidth, outHeight];
// scanning through each (x,y) pixel of the image--+
for (int y = 0; y < inHeight; y++) //|
{ //|
for (int x = 0; x < inWidth; x++)//<-----------+
{
if (image[x, y] != 0)//if a pixel is black, skip it.
{
// We are drawing some Sine waves. So, it may
// vary from -90 to +90 degrees.
for (int theta = -outHeightHalf; theta < outHeightHalf; theta++)
{
double rad = theta * Math.PI / 180;
// respective radius value is computed
//int radius = (int)Math.Round(Math.Cos(rad) * (x - inWidthHalf) - Math.Sin(rad) * (y - inHeightHalf));
//int radius = (int)Math.Round(Math.Cos(rad) * (x + inWidthHalf) - Math.Sin(rad) * (y + inHeightHalf));
int radius = (int)Math.Round(Math.Cos(rad) * (x) - Math.Sin(rad) * (outHeight - y));
// if the radious value is between 1 and
if ((radius > 0) && (radius <= outWidth))
{
houghMap[radius, theta + outHeightHalf]++;
}
}
}
}
}
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bitmap bitmap = (Bitmap)pictureBox1.Image as Bitmap;
int[,] intImage = ToInteger(bitmap);
HoughMap houghMap = new HoughMap();
houghMap.image = intImage;
houghMap.Compute();
int[,] normalized = Rescale(houghMap.houghMap);
Bitmap hough = ToBitmap(normalized, bitmap.PixelFormat);
pictureBox2.Image = hough;
}
public static int[,] Rescale(int[,] image)
{
int[,] imageCopy = (int[,])image.Clone();
int Width = imageCopy.GetLength(0);
int Height = imageCopy.GetLength(1);
int minVal = 0;
int maxVal = 0;
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
double conv = imageCopy[i, j];
minVal = (int)Math.Min(minVal, conv);
maxVal = (int)Math.Max(maxVal, conv);
}
}
int minRange = 0;
int maxRange = 255;
int[,] array2d = new int[Width, Height];
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
array2d[i, j] = (maxRange - minRange) * (imageCopy[i,j] - minVal) / (maxVal - minVal) + minRange;
}
}
return array2d;
}
public int[,] ToInteger(Bitmap input)
{
int Width = input.Width;
int Height = input.Height;
int[,] array2d = new int[Width, Height];
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Color cl = input.GetPixel(x, y);
int gray = (int)Convert.ChangeType(cl.R * 0.3 + cl.G * 0.59 + cl.B * 0.11, typeof(int));
array2d[x, y] = gray;
}
}
return array2d;
}
public Bitmap ToBitmap(int[,] image, PixelFormat pixelFormat)
{
int[,] imageCopy = (int[,])image.Clone();
int Width = imageCopy.GetLength(0);
int Height = imageCopy.GetLength(1);
Bitmap bitmap = new Bitmap(Width, Height, pixelFormat);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
int iii = imageCopy[x, y];
Color clr = Color.FromArgb(iii, iii, iii);
bitmap.SetPixel(x, y, clr);
}
}
return bitmap;
}
}
I have solved the problem from this link. The source code from this link is the best one I have ever came across.
public class HoughMap
{
public int[,] houghMap { get; private set; }
public int[,] image { get; set; }
public void Compute()
{
if (image != null)
{
// get source image size
int Width = image.GetLength(0);
int Height = image.GetLength(1);
int centerX = Width / 2;
int centerY = Height / 2;
int maxTheta = 180;
int houghHeight = (int)(Math.Sqrt(2) * Math.Max(Width, Height)) / 2;
int doubleHeight = houghHeight * 2;
int houghHeightHalf = houghHeight / 2;
int houghWidthHalf = maxTheta / 2;
houghMap = new int[doubleHeight, maxTheta];
// scanning through each (x,y) pixel of the image--+
for (int y = 0; y < Height; y++) //|
{ //|
for (int x = 0; x < Width; x++)//<-------------+
{
if (image[x, y] != 0)//if a pixel is black, skip it.
{
// We are drawing some Sine waves.
// It may vary from -90 to +90 degrees.
for (int theta = 0; theta < maxTheta; theta++)
{
double rad = theta *Math.PI / 180;
// respective radius value is computed
int rho = (int)(((x - centerX) * Math.Cos(rad)) + ((y - centerY) * Math.Sin(rad)));
// get rid of negative value
rho += houghHeight;
// if the radious value is between
// 1 and twice the houghHeight
if ((rho > 0) && (rho <= doubleHeight))
{
houghMap[rho, theta]++;
}
}
}
}
}
}
}
}
Just look at this C++ code, and this C# code. So, complicated and messy that my brain got arrested. Especially, the C++ one. I never anticipated someone to store 2D values in a 1D array.
I have a simple question. How can I shift a linear array in 3 dimensions?
It seems too work but in the X & Y axis i got an index problem.
The reson why I wanna do this is simple. I want to create a volumetric terrain with a chunk buffer, so i only have to recalulate values on the edges when the viewport is moving.
I have read an article about this system :
Essentially they provide a way to scroll a potentially infinite data
field through a fixed size multi-resolution cache.
So my pipline for the generation part would be:
When viewport moves get axis
Shift the axis
Generate some noise only for the new cells
Triangulate the new cells
Update all cell positions
Here are my other images:
http://forum.unity3d.com/threads/array-shifting-wrong-index-i-x-y-size-z-size-size.425448/#post-2751774
Nobody in the unity forums could answer my question...
public int size;
public float speed;
private byte[] volume;
private byte[] shifted;
public bool widthShift, heightShift, depthShift;
private int widthOffset = 0;
private int heightOffset = 0;
private int depthOffset = 0;
private float time = 0;
private int cube;
void Start()
{
volume = new byte[size * size * size];
shifted = new byte[size * size * size];
cube = size * size * size;
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
for(int z = 0; z < size; z++)
volume[x + y * size + z * size * size] = (x == 0 || y == 0 || z == 0) ? (byte)1 : (byte)0;
}
void Update()
{
time += Time.fixedDeltaTime * speed;
if (time > 1)
{
time = 0;
widthOffset = (widthOffset >= size) ? 0 : widthOffset;
heightOffset = (heightOffset >= size) ? 0 : heightOffset;
depthOffset = (depthOffset >= size) ? 0 : depthOffset;
if (widthShift)
widthOffset++;
else
widthOffset = 0;
if (heightShift)
heightOffset++;
else
heightOffset = 0;
if (depthShift)
depthOffset++;
else
depthOffset = 0;
Shift(widthOffset, heightOffset, depthOffset);
}
}
void Shift(int xOff, int yOff, int zOff)
{
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
for(int z = 0; z < size; z++)
{
int i = ((x + xOff) + (y + yOff) * size + (z + zOff) * size * size);
i = (i >= cube) ? (i - cube) : i;
shifted[x + y * size + z * size * size] = volume[i];
}
}
void OnDrawGizmos()
{
if(Application.isPlaying)
for(int x = 0; x < size; x++)
for(int y = 0; y < size; y++)
for(int z = 0; z < size; z++)
{
Gizmos.color = (shifted[x + y * size + z * size * size] == 1) ? new Color32(0, 255, 0, 255) : new Color32(255, 0, 0, 4);
Gizmos.DrawWireCube(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f), new Vector3(0.95f, 0.95f, 0.95f));
}
}
Give it a try:
void Shift(int xOff, int yOff, int zOff)
{
for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
for(int z = 0; z < size; z++)
{
int nx = (x + xOff) % size;
int ny = (y + yOff) % size;
int nz = (z + zOff) % size;
int i = (nx + ny * size + nz * size * size);
shifted[x + y * size + z * size * size] = volume[i];
}
}
I have my image cropping app based on:
http://www.c-sharpcorner.com/UploadFile/55275a/windowsphone-image-crop-with-rectangle/
I modified it a little bit so I can resize rectangle instead of creating new
so my whole method look like:
private async void Accept_Click(object sender, EventArgs e)
{
WriteableBitmap wb = new WriteableBitmap(image);
double originalImageWidth = wb.PixelWidth;
double originalImageHeight = wb.PixelHeight;
double displayedWidth = image1.ActualWidth;
double displayedHeight = image1.ActualHeight;
double widthRatio = originalImageWidth / displayedWidth;
double heightRatio = originalImageHeight / displayedHeight;
r = (Rectangle) (from c in LayoutRoot.Children
where c.Opacity == .5 select c).First();
GeneralTransform gt = r.TransformToVisual(LayoutRoot);
Point p = gt.Transform(new Point(0, 0));
Point1 = (r.TransformToVisual(this)).Transform(new Point(0, 0));
Point2 = new Point(Point1.X + r.Width, Point1.Y + r.Height);
WriteableBitmap newImage = new WriteableBitmap(
(int) (widthRatio * Math.Abs(Point2.X - Point1.X)),
(int) (heightRatio * Math.Abs(Point2.Y - Point1.Y)));
int xoffset = (int) (((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio);
int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
if (newImage.Pixels.Length > 0)
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int) ((i % newImage.PixelWidth) + xoffset);
int y = (int) ((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
}
using (MemoryStream ms = new MemoryStream())
{
newImage.SaveJpeg(ms, (int) newImage.PixelWidth,
(int) newImage.PixelHeight, 0, 100);
image.SetSource(ms);
}
}
else
{
}
ProgressBar pb = new ProgressBar();
pb.IsEnabled = true;
LayoutRoot.Children.Add(pb);
int idReceipt = (int) PhoneApplicationService.Current.State["paragon"];
await ReceiptsHelper.addPhotosToReceipt(image, idReceipt);
NavigationService.Navigate(new Uri("/7.0/StronaParagonu.xaml", UriKind.Relative));
}
When my image is vertical everything works fine, but when my image is horizontal I get Array Index Out Of Bounds Exception at:
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
I don't know exactly what am I doing wrong.
Anybody can help?
EDIT:
I changed my code to:
if (wb.PixelWidth > wb.PixelHeight)
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int)((i % newImage.PixelWidth) + xoffset);
int y = (int)((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];
}
}
else
{
for (int i = 0; i < newImage.Pixels.Length; i++)
{
int x = (int)((i % newImage.PixelWidth) + xoffset);
int y = (int)((i / newImage.PixelWidth) + yoffset);
newImage.Pixels[i] = wb.Pixels[y * wb.PixelWidth + x];
}
}
In result I've got something like this
Maybe there is some workaround in which I can flip image 90 degree?
I tried WriteableBitmapEx but it doesnt work.
First thing I see is:
int yoffset = (int) (((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
I guess there should be Point2.Y?
Second thing is what #Rashed mentioned in comment:
When you want get horizontal image, you must change X and Y place: newImage.Pixels[i] = wb.Pixels[x * wb.PixelHeight + y];
But please take a note I'm really guessing here since it's late and I don't see sharp ;-)