Trying to position all chunks for distinct LoD levels - c#

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.

Related

C# Visual Studio thinks my class ends before it does

I have a normal class with no errors, but visual studio thinks the class ends before it should. It thinks the c* bracket of the whole class itself. Can you help me? I will show you a photo of what I mean:
You can see what I mean with the picture: the class ends where it shouldn't. I have already tried erasing a adding new brackets, copy and paste, and almost anything you can think of.
EDIT:
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using LukeWaffel.BUI;
using UnityEngine.UI;
public class Pattern : MonoBehaviour
{
public Text levelTxt;
public GameObject[] displayRow;
//a messageBox instance that can be used many times
private UIBox box;
public GameObject displayPrefab;
public GameObject displayBlockParent;
public GameObject userPrefab;
public GameObject userBlockParent;
public GameObject[] userRow;
//an array that is used for a function to check if all boolians in the array are true
private bool[] alltrue;
public int zNum;
public int xNum;
public int yNum;
private Color[] colors;
private bool isHardGenerate = false;
//the space between blocks needed to create a table
private float offset;
//how many colors are currently at play for exapmle: colorNum = 2 (the colors allowed in a pattern are red and yellow)
private int colorNum = 2;
// a variable that indicates the amount of colored blocks in a pattern
private int numToColor = 0;
public static int level = 0;
// a class that indicates which blocks are active: user or display;
private BlockController b;
// Start is called before the first frame update
private void Start()
{
levelTxt.text = "Level: " + (level + 1);
//initialize the colors available in the current game.
List<Color> colorsTemp = new List<Color>();
colorsTemp.Add(Color.red);
colorsTemp.Add(Color.yellow);
colorsTemp.Add(Color.green);
//convert the colors to array. the list was there just to add the colors hence thte name colorsTemp
colors = colorsTemp.ToArray<Color>();
//the blockController class controls how much time the user has to see the pattern before it is drawn
b = gameObject.GetComponent<BlockController>();
offset = 1f;
//start to generate the pattern
GenerateEasy();
}
private void GenerateEasy()
{
//set the number of colored blocks(randomized) GetRandomFloat is a custom function created to decide the skip of the randomized number. By defult that value is 0.5f
private float rnd = GetRandomFloat(1, 4);
if(rnd == 1)//that means that all blocks would be colored and thats an easy pattern. because of that we need to change the number
{
rnd++;
}
//the formula to decide how many blocks will be colored
numToColor = Mathf.CeilToInt((Num* xNum * yNum)/rnd);
// Create empty grid
displayRow = new GameObject[zNum * xNum * yNum];
userRow = new GameObject[zNum * xNum * yNum];
alltrue = new bool[yNum * xNum * zNum];
// Create blocks
for (int i = 0; i<yNum; i++)
{
for (int j = 0; j<xNum; j++)
{
for (int k = 0; k<zNum; k++)
{
//creating display table we are not selecting the pattern yet.
GameObject g = Instantiate(displayPrefab, new Vector3(j * offset, i * offset, k * offset), Quaternion.Euler(180, 0, 0), displayBlockParent.transform);
displayRow[i * (xNum * zNum) + j * zNum + k] = g;
//creating the coloring table (in all variables named build/user)
GameObject o = Instantiate(userPrefab, new Vector3(j * offset, i * offset, k * offset), Quaternion.Euler(180, 0, 0), userBlockParent.transform);
userRow[i * (xNum * zNum) + j * zNum + k] = o;
userRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color = colors[0];
}
}
}
//reverse the array because by defult the blocks are upside down, so we need to correct that and flip all the blocks again
Array.Reverse(displayRow);
Array.Reverse(userRow);
//create pattern for the display table. notice in the for loop the outer for loop runs numToColor times, the amount of blocks that should be colored
for (int s = 0; s<numToColor; s++)
{
//the for loop runs once too much, so in the first loop we need to not make any actions, unless num to color is 1, and then it only runs one time.
if (numToColor != 1 && s == 0)
{
continue;
}
//initialize the colored and notcolored lists. this only exists in generateEasy because this makes the pattern easier to remember. colored are the blocks that are not good for coloring and not colored are the blocks viable to color.
List<GameObject> colored = new List<GameObject>();
List<GameObject> notColored = new List<GameObject>();
//if non of the blocks are colored yet, color a block randomly
if (displayRow.ToList<GameObject>().All(p => p.GetComponent<Renderer>().material.color == colors[0]))
{
int randomIndex = UnityEngine.Random.Range(0, yNum * xNum * zNum);
displayRow[randomIndex].GetComponent<Renderer>().material.color = colors[UnityEngine.Random.Range(1, colorNum)];
}
//this for checks if any of the blocks that exist contain a color that isn't red(the defult color)
for (int i = 0; i<yNum; i++)
{
for (int j = 0; j<xNum; j++)
{
for (int k = 0; k<zNum; k++)
{
//the colors array are all the available colors in the game. because red is the defult color and the first one in the array, it does not count as a colored block and therefor need to be skipped for the if statment.
if (colors.Skip(1).Any(p => p == displayRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color))
{
//adding the colored blocks to the colored array, which helps later for the formula for the easy pattern, and at the same time making them unable to be recolored accidently by the pattern.
colored.Add(displayRow[i * (xNum * zNum) + j * zNum + k]);
}
}
}
}
//thia doe loop checks if the block that's not already colored is viable for being colored for the easy level. if it is, it adds the block to the notColored array
for (int i = 0; i<yNum; i++)
{
for (int j = 0; j<xNum; j++)
{
for (int k = 0; k<zNum; k++)
{
if (displayRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color == colors[0] && (colored.Any(p => (j != xNum - 1 && GameObject.ReferenceEquals(p, displayRow[i * (xNum * zNum) + (j + 1) * zNum + k]))
|| (j != 0 && GameObject.ReferenceEquals(p, displayRow[i * (xNum * zNum) + (j - 1) * zNum + k]))
|| (i != 0 && GameObject.ReferenceEquals(p, displayRow[(i - 1) * (xNum * zNum) + j * zNum + k]))
|| (i != yNum - 1 && GameObject.ReferenceEquals(p, displayRow[(i + 1) * (xNum * zNum) + j * zNum + k]))
|| (k != 0 && GameObject.ReferenceEquals(p, displayRow[i * (xNum * zNum) + j * zNum + k - 1]))
|| (k != zNum - 1 && GameObject.ReferenceEquals(p, displayRow[i * (xNum * zNum) + j * zNum + k + 1])))))
{
notColored.Add(displayRow[i * (xNum * zNum) + j * zNum + k]);
}
}
}
}
//finally, one of the not colored blocks in the not colored array is randomly colored with a random color according to level.
notColored.ToArray()[UnityEngine.Random.Range(0, notColored.ToArray().Length)].GetComponent<Renderer>().material.color = colors[UnityEngine.Random.Range(1, colorNum)];
}
}
private void GenerateHard()
{
//up until the very end, Generate hard is extremley similar to easyGenerate. if you want detailed comment on most of the function, please refer to easy generate.
//set the number of colored blocks
float rnd = GetRandomFloat(1, 4);
if (rnd == 1)
{
rnd++;
}
numToColor = Mathf.CeilToInt((zNum * xNum * yNum) / rnd);
displayRow = new GameObject[zNum * xNum * yNum];
userRow = new GameObject[zNum * xNum * yNum];
alltrue = new bool[yNum * xNum * zNum];
for (int i = 0; i < yNum; i++)
{
for (int j = 0; j < xNum; j++)
{
for (int k = 0; k < zNum; k++)
{
GameObject g = Instantiate(displayPrefab, new Vector3(j * offset, i * offset, k * offset), Quaternion.Euler(180, 0, 0), displayBlockParent.transform);
displayRow[i * (xNum * zNum) + j * zNum + k] = g;
GameObject o = Instantiate(userPrefab, new Vector3(j * offset, i * offset, k * offset), Quaternion.Euler(180, 0, 0), userBlockParent.transform);
userRow[i * (xNum * zNum) + j * zNum + k] = o;
userRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color = colors[0];
}
}
}
Array.Reverse(displayRow);
Array.Reverse(userRow);
//create a pattern. for now it is the same as easy generate but it's going to get different soon.
for (int s = 1; s < numToColor; s++)
{
List<GameObject> colored = new List<GameObject>();
List<GameObject> notColored = new List<GameObject>();
if (displayRow.ToList<GameObject>().All(p => p.GetComponent<Renderer>().material.color == colors[0]))
{
int randomIndex = UnityEngine.Random.Range(0, yNum * xNum * zNum);
displayRow[randomIndex].GetComponent<Renderer>().material.color = colors[UnityEngine.Random.Range(1, colorNum)];
}
for (int i = 0; i < yNum; i++)
{
for (int j = 0; j < xNum; j++)
{
for (int k = 0; k < zNum; k++)
{
if (colors.Skip(1).Any(p => p == displayRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color))
{
colored.Add(displayRow[i * (xNum * zNum) + j * zNum + k]);
}
}
}
}
//now is the different part, the for loop does not check if the block will be viable for an easy pattern, it just adds every blocks that's not colored, even if that block makes the pattern much harder
for (int i = 0; i < yNum; i++)
{
for (int j = 0; j < xNum; j++)
{
for (int k = 0; k < zNum; k++)
{
if (displayRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color == colors[0])
{
notColored.Add(displayRow[i * (xNum * zNum) + j * zNum + k]);
}
}
}
}
//like before, the progranm chooses to color a block in the not coloed array randomly.
notColored.ToArray()[UnityEngine.Random.Range(0, notColored.ToArray().Length)].GetComponent<Renderer>().material.color = colors[UnityEngine.Random.Range(1, colorNum)];
}
}
// Update is called once per frame
private void Update()
{
//this huge outer if is resposible for cheking the pattern
if (Input.GetKeyDown(KeyCode.Return) && !CrossHair.ok)
{
for (int i = 0; i < yNum; i++)
{
for (int j = 0; j < xNum; j++)
{
for (int k = 0; k < zNum; k++)
{
//checks if the pattern is exactly equal to what the user has colored
if (displayRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color.Equals(userRow[i * (xNum * zNum) + j * zNum + k].GetComponent<Renderer>().material.color))
{
alltrue[i * (xNum * zNum) + j * zNum + k] = true;
}
else
{
alltrue[i * (xNum * zNum) + j * zNum + k] = false;
}
}
}
}
//if the user got the pattern right then...
if (alltrue.ToList<bool>().All(b => b))
{
if ((level + 1) % 10 != 0 && level + 1 != 0)
{
//make the mouse appear and make the user unable to move the player or color any blocks so that the user can focus on the messegebox
CrossHair.ok = true;
Cursor.lockState = CursorLockMode.None;
Cursor.lockState = CursorLockMode.Confined;
Cursor.visible = true;
//display the message bix
box = new UIBox("bID", BUI.UIType.Message);
box.header = "You have passed the level!";
box.body = "You have passed this current level. Have you got what it takes to take on the next Puzzle?";
box.buttons.Add(new UIButton("Yes, next level!", FuncButton));
BUI.Instance.AddToQueue(box);
//reset everything for the next level. also increases the level.
b.Reset();
level++;
levelTxt.text = "Level: " + (level + 1);
DestroyArray(userRow);
DestroyArray(displayRow);
//generate hard and generate easy switch turns.
if (!isHardGenerate)
{
yNum++;
isHardGenerate = true;
GenerateHard();
}
else
{
isHardGenerate = false;
xNum++;
GenerateEasy();
}
}
//every 10 levels a color is added to the table.
else
{
Debug.Log("passed level 10");
CrossHair.ok = true;
Cursor.lockState = CursorLockMode.None;
Cursor.lockState = CursorLockMode.Confined;
Cursor.visible = true;
box = new UIBox("bID", BUI.UIType.Message);
box.header = "You have passed the level!";
box.body = "You have passed this current level. Have you got what it takes to take on the next Puzzle?";
box.buttons.Add(new UIButton("Yes, next level!", FuncButton));
BUI.Instance.AddToQueue(box);
xNum = 2;
yNum = 2;
colorNum++;
b.Reset();
level++;
levelTxt.text = "Level: " + (level + 1);
DestroyArray(userRow);
DestroyArray(displayRow);
isHardGenerate = false;
GenerateEasy();
}
}
//if the user lost then...
else
{
//for this refer to the beginning of the if statment
CrossHair.ok = true;
Cursor.lockState = CursorLockMode.None;
Cursor.lockState = CursorLockMode.Confined;
Cursor.visible = true;
box = new UIBox("bID", BUI.UIType.Message);
box.header = "You have failed";
box.body = "You have failed this current level. Have you got what it takes to try again?";
box.buttons.Add(new UIButton("Yes, try this level again!", FuncButton));
BUI.Instance.AddToQueue(box);
//if level doesnt equal to 0, go down a levle, you cant go down from the first level.
if (level != 0)
level--;
b.Reset();
levelTxt.text = "Level: " + (level + 1);
DestroyArray(userRow);
DestroyArray(displayRow);
if (isHardGenerate)
{
yNum--;
isHardGenerate = false;
GenerateEasy();
}
else
{
if (level != 0)
{
isHardGenerate = true;
xNum--;
GenerateHard();
}
else
{
GenerateEasy();
}
}
}
//destroys every onject in an array
void DestroyArray(GameObject[] b)
{
foreach (GameObject k in b)
Destroy(k.gameObject);
}
//lets the player move again and cloles the message box
void FuncButton(UIBox boxInfo, UIButton buttonInfo)
{
CrossHair.ok = false;
BUI.Instance.CloseBox(box.id);
}
}
}
//go to refrence to find the meaning of the function. (in easyGenerate.)
public float GetRandomFloat(int min, int max, float value = 0.5f)
{
int multipliedMin = (int)(min / value);
int multipliedMax = (int)(max / value);
return ((float)UnityEngine.Random.Range(multipliedMin, multipliedMax)) * value;
}
}
Remove private in private float rnd = GetRandomFloat(1, 4);
Take a look at the official documentation here in order to understand the access modifiers.
You're declaring a property inside a method. These should go within the initial class braces.

How to construct a graph of weights from an image

Project: intelligence scissors.
The first part of the project is to load an image (in the form of RGBPixel 2d array) then to construct a graph of weights to use it later to determine the shortest path between 2 points on the image (the 2 points will be determined by an anchor and a free point..In short i will have the source and the destination points).
I have a function that open the image and return a RGBPixel 2d array already made.Now image is loaded i want to construct the graph to do the i should use a function called CalculatePixelEnergies here is the code
public static Vector2D CalculatePixelEnergies(int x, int y, RGBPixel[,] ImageMatrix)
{
if (ImageMatrix == null) throw new Exception("image is not set!");
Vector2D gradient = CalculateGradientAtPixel(x, y, ImageMatrix);
double gradientMagnitude = Math.Sqrt(gradient.X * gradient.X + gradient.Y * gradient.Y);
double edgeAngle = Math.Atan2(gradient.Y, gradient.X);
double rotatedEdgeAngle = edgeAngle + Math.PI / 2.0;
Vector2D energy = new Vector2D();
energy.X = Math.Abs(gradientMagnitude * Math.Cos(rotatedEdgeAngle));
energy.Y = Math.Abs(gradientMagnitude * Math.Sin(rotatedEdgeAngle));
return energy;
}
This function use CalculateGradientAtPixel, Here is the code in case you want it.
private static Vector2D CalculateGradientAtPixel(int x, int y, RGBPixel[,] ImageMatrix)
{
Vector2D gradient = new Vector2D();
RGBPixel mainPixel = ImageMatrix[y, x];
double pixelGrayVal = 0.21 * mainPixel.red + 0.72 * mainPixel.green + 0.07 * mainPixel.blue;
if (y == GetHeight(ImageMatrix) - 1)
{
//boundary pixel.
for (int i = 0; i < 3; i++)
{
gradient.Y = 0;
}
}
else
{
RGBPixel downPixel = ImageMatrix[y + 1, x];
double downPixelGrayVal = 0.21 * downPixel.red + 0.72 * downPixel.green + 0.07 * downPixel.blue;
gradient.Y = pixelGrayVal - downPixelGrayVal;
}
if (x == GetWidth(ImageMatrix) - 1)
{
//boundary pixel.
gradient.X = 0;
}
else
{
RGBPixel rightPixel = ImageMatrix[y, x + 1];
double rightPixelGrayVal = 0.21 * rightPixel.red + 0.72 * rightPixel.green + 0.07 * rightPixel.blue;
gradient.X = pixelGrayVal - rightPixelGrayVal;
}
return gradient;
}
In my code of graph construction i decided to make a 2d double array to hold the weights, here what i do but it seems to be a wrong construction
public static double [,] calculateWeights(RGBPixel[,] ImageMatrix)
{
double[,] weights = new double[1000, 1000];
int height = ImageOperations.GetHeight(ImageMatrix);
int width = ImageOperations.GetWidth(ImageMatrix);
for (int y = 0; y < height - 1; y++)
{
for (int x = 0; x < width - 1; x++)
{
Vector2D e;
e = ImageOperations.CalculatePixelEnergies(x, y, ImageMatrix);
weights[y + 1, x] = 1 / e.X;
weights[y, x + 1] = 1 / e.Y;
}
}
return weights;
}
an example for an image
an other example for an image

Read microphone decibels and pitch/frequency

I am trying to make a game in which my character shoots when a loud enough sound is heard true the mic (in Unity). I have however no idea how to start.
Thank you for your help!
You can get the decibels from a Microphone by retrieving the block of the currently playing Microphone's output data with the AudioSource.GetOutputData function. To get the dB from this data, you need sum the data samples then calculate the RMS. That's RMS value you can use to calculate the dB with 20 * Mathf.Log10 (RMS / refVal).
There is a complete example on about this on Unity's post. You can read that for more information and the code below is based on that:
public float rmsVal;
public float dbVal;
public float pitchVal;
private const int QSamples = 1024;
private const float RefValue = 0.1f;
private const float Threshold = 0.02f;
float[] _samples;
private float[] _spectrum;
private float _fSample;
void Start()
{
_samples = new float[QSamples];
_spectrum = new float[QSamples];
_fSample = AudioSettings.outputSampleRate;
}
void Update()
{
AnalyzeSound();
Debug.Log("RMS: " + rmsVal.ToString("F2"));
Debug.Log(dbVal.ToString("F1") + " dB");
Debug.Log(pitchVal.ToString("F0") + " Hz");
}
void AnalyzeSound()
{
GetComponent<AudioSource>().GetOutputData(_samples, 0); // fill array with samples
int i;
float sum = 0;
for (i = 0; i < QSamples; i++)
{
sum += _samples[i] * _samples[i]; // sum squared samples
}
rmsVal = Mathf.Sqrt(sum / QSamples); // rms = square root of average
dbVal = 20 * Mathf.Log10(rmsVal / RefValue); // calculate dB
if (dbVal < -160) dbVal = -160; // clamp it to -160dB min
// get sound spectrum
GetComponent<AudioSource>().GetSpectrumData(_spectrum, 0, FFTWindow.BlackmanHarris);
float maxV = 0;
var maxN = 0;
for (i = 0; i < QSamples; i++)
{ // find max
if (!(_spectrum[i] > maxV) || !(_spectrum[i] > Threshold))
continue;
maxV = _spectrum[i];
maxN = i; // maxN is the index of max
}
float freqN = maxN; // pass the index to a float variable
if (maxN > 0 && maxN < QSamples - 1)
{ // interpolate index using neighbours
var dL = _spectrum[maxN - 1] / _spectrum[maxN];
var dR = _spectrum[maxN + 1] / _spectrum[maxN];
freqN += 0.5f * (dR * dR - dL * dL);
}
pitchVal = freqN * (_fSample / 2) / QSamples; // convert index to frequency
}

C# windows form render isometric tile

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

Converting a fisheye image to landscape and diving it into four parts using c#

I have an fisheye image and what I am trying to do is convert it into landscape.
The code I have written converts it into landscape but when it comes to divding it into different parts it adds black parts to them.
Can anyone help
using System;
using System.Drawing;
namespace fisheye_image
{
class Program
{
static void Main()
{
// assume the source image is square, and its width has even number of pixels
Bitmap bm = (Bitmap)Image.FromFile(#"C:\Users\abc\Desktop\lillestromfisheye.jpg");
int l = bm.Width / 2;
int i, j;
int x, y;
double radius, theta;
// calculated indices in Cartesian coordinates with trailing decimals
double fTrueX, fTrueY;
int iSourceWidth = (2 * l);
int run = 0, lastWidth = 1;
while (run<4)
{
Bitmap bmDestination = new Bitmap(lastWidth*l, l);
for (i = 0; i < bmDestination.Height; ++i)
{
radius = (double)(l - i);
for (j = run*l; j < lastWidth*l ; ++j)
{
// theta = 2.0 * Math.PI * (double)(4.0 * l - j) / (double)(4.0 * l);
theta = 2.0 * Math.PI * (double)(-j) / (double)(4.0 * l);
fTrueX = radius * Math.Cos(theta);
fTrueY = radius * Math.Sin(theta);
// "normal" mode
x = (int)(Math.Round(fTrueX)) + l;
y = l - (int)(Math.Round(fTrueY));
// check bounds
if (x >= 0 && x < iSourceWidth && y >= 0 && y < iSourceWidth)
{
bmDestination.SetPixel(j, i, bm.GetPixel(x, y));
}
}
}
bmDestination.Save(#"C:\Users\abc\Desktop\fisheyelandscape"+run.ToString()+".jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
run++;
lastWidth++;
}
}
}
}
Below are the original and processed images
We just need to add another variable 'k' in the second for loop that goes from zero to the width of destination image.
while (run<4)
{
Bitmap bmDestination = new Bitmap(l, l);
for (i = 0; i < bmDestination.Height; ++i)
{
radius = (double)(l - i);
for (j = run * l, k = 0; j < lastWidth * l||k < bmDestination.Width; ++j, ++k)
{
// theta = 2.0 * Math.PI * (double)(4.0 * l - j) / (double)(4.0 * l);
theta = 2.0 * Math.PI * (double)(-j) / (double)(4.0 * l);
fTrueX = radius * Math.Cos(theta);
fTrueY = radius * Math.Sin(theta);
// "normal" mode
x = (int)(Math.Round(fTrueX)) + l;
y = l - (int)(Math.Round(fTrueY));
// check bounds
if (x >= 0 && x < iSourceWidth && y >= 0 && y < iSourceWidth)
{
bmDestination.SetPixel(k, i, bm.GetPixel(x, y));
}
}

Categories

Resources