Problem with duty cycle (rectangular wave) with drawline C# - c#

I need to draw a rectangular wave using drawline, depending on the duty cycle, the frequency, and the amplitude (using trackbars). Everything is working fine, except for the duty cycle.
Here is the formula for my wave, which is basically a square wave :
double y = Math.Sign(Math.Sin(x / 180 * Math.PI)) * amplitude.Value;
I'm using a pictureBox in order to draw it (every integers are only here for a better display on the pictureBox):
private void P_ZoneDeTrace_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen myPen = new Pen(Color.Green);
double x1 = 10;
double y1 = 0;
for (double x = 1; x < pictureBox1.Width*10; x++)
{
double y = Math.Sign(Math.Sin(x / 180 * Math.PI)) * amplitude.Value;
g.DrawLine(myPen, (float)x1, (float)y1 + 120, (float)(x / fréquence.Value) + 10, (float)y + 120);
x1 = x / fréquence.Value + 10;
y1 = y;
}}
I have now a regular square wave. Now I need to transform it into a rectangular wave, using the duty cyle, which is a trackbar, going from 0 to 10. If it's equal to 0, the wave is always at -1, and if it's equal to 10, the wave is always at 1.
In my else I tried to manage the wave when the duty cycle is between 1 and 9 :
close to 1, every pattern has to stay longer at -1
close to 9, every pattern has to stay longer at 1
Here is the code, right under the y formula, to do that :
int i = 0;
int val = 0;
if (rapport.Value == 0)
{
if (y < 0)
{
y = y * -1;
}
}
if (rapport.Value == 10)
{
if (y > 0)
{
y = y * -1;
}
}
else
{
if (y>0 && i < rapport.Value *18 && val==0)
{
y = y * -1;
i++;
}
if (y > 0 && i == (rapport.Value * 18))
{
val = 1;
}
if (y < 0 && val == 1)
{
i = 0;
val = 0;
}
}
I multiply "y" by -1 to go from -1 to 1 and conversely. "rapport" is the duty cycle, and it's multiplied by 18 in order to be proportional with my wave.
"val" help me to modify other patterns than the first one (if I don't use "val", only the first one is modified)
The problem is that only the first pattern is working well, as described before. For other patterns, the wave is staying to long at 1 when duty cycle is close to 1 (and conversely if it's close to 9).
Here is the full signal :
The first pattern, which is right :
Other patterns, wrong, and that should be the same as the first one :
Every patterns should be the same as the first one, and as you can see, it's not working. They are moving using the trackbar, but not enough, the most beeing as the picture above).
If you could help me to resolve this problem, every pattenrs having to behave as the 1st one ? thanks in advance.

Related

How can I make a hole at a specific place using script (unity)

I am working on making a hole in the terrain in real-time with a mouse click. I found this script which allows the user to raise terrain at a circle shape with a mouse click and I tried to add the code to generate a hole to it like so :
void PaintCircle(Vector3 point )
{
int x ;
int z;
int heightX;
int heightZ;
float heightY;
Vector2 calc ;
var b = new bool[heightmapWidth-1, heightmapHeight-1];
for (z = -circleRadius; z <= circleRadius; z++)
{
for (x = -circleRadius; x <= circleRadius; x++)
{
// for a circle, calcualate a relative Vector2
calc = new Vector2(x, z);
// check if the magnitude is within the circle radius
if (calc.magnitude <= circleRadius)
{
// is within circle, paint height
heightX = (int)(point.x + x);
heightZ = (int)(point.z + z);
// check if heightX and Z is within the heightmapData array size
if (heightX >= 0 && heightX < heightmapWidth && heightZ >= 0 && heightZ < heightmapHeight)
{
// read current height
heightY = heightmapData[heightZ, heightX]; // note that in heightmapData, X and Z are reversed
// add paintWeight to the current height
heightY -= paintWeight;
// reach the bottom terrain.terrainData.GetHeight((int)heightmapPos.x, (int)heightmapPos.z)
// update heightmapData array
heightmapData[heightZ, heightX] = heightY;
b[heightZ, heightX] = (heightX < 20 && heightX > 80 && heightZ < 20 && heightZ > 80);
}
}
}
}
terrain.terrainData.SetHoles(0, 0, b);
// apply new heights to terrainData
terrainData.SetHeights(0, 0, heightmapData);
}
I added the raise terrain and the hole together because I need them to work together. Unfortunately, this did not work all of the terrains disappeared so I tried to invert the area where the hole should be like this :
b[heightZ, heightX] = !(heightX < 20 && heightX > 80 && heightZ < 20 && heightZ > 80);
but it gave me what I want in reverse, the area where the hole should remain and all the other terrain disappeared so I thought that the problem could be in this line
var b = new bool[heightmapWidth-1, heightmapHeight-1];
so I changed it to this :
bool[,] b = terrainData.GetHoles(0, 0, heightmapWidth, heightmapHeight);
but it gave me this error :
ArgumentException: Trying to access out-of-bounds terrain holes information.
UnityEngine.TerrainData.GetHoles (System.Int32 xBase, System.Int32 yBase, System.Int32 width, System.Int32 height)
I am out of ideas so I am hoping if someone can tell me what is the problem and how can I fix it
the solution was this :
bool[,] b = terrainData.GetHoles(0, 0, heightmapWidth-1, heightmapHeight-1);

Trying to create squares in a row in a said angle, somehow created the fibonacci spiral

My Program will ideally create a series of stacked squares based on 2 variables. 1 Is the amount of squares per series and the other is how many series there will be. each series is branched out from the center of the screen at different angles spaced evenly apart. If there are 2 series, one will be facing 0 degrees and the other will be facing 180 degrees. If there is 3, the first will be facing 0 degrees, second will face 120, and third will face 240. Somewhere in my math or my method of making this effect, I messed up bad.
The current result is, for some reason, the Fibonacci spiral. Here is the Are the suspected functions below (with all variable definitions)
also, button is a class I made and not a typo:
public button Led; //Object used to create series
public Slider ledNumber;// controls how many LEDS there are per series
public Slider IncrementsPerRotation;//Controls how many series there are
public Text ledText;//text above ledNumber slider
public Text incrementText;//text above IncrementsPerRotation Slider
public Transform canvas;//Canvas where objects will be created
List<List<button>> LedConfig = new List<List<button>>();//where all the LEDs will be stored
private float buttonW, middleX,middleY; // the width of the LED and the middle values of the screen
private int prevLed = 0, prevIncrements = 0;// previous values for both sliders
// Start is called before the first frame update
void Start()
{
buttonW = Led.transform.localScale.x;// set LED width
Vector2 temp = Camera.main.ScreenToWorldPoint(new Vector2 (Screen.width / 2, Screen.height / 2));// get middle values
//assign middle values
middleX = temp.x;
middleY = temp.y;
}
// Update is called once per frame
void Update()
{
if (prevLed != (int)ledNumber.value && (int)ledNumber.value > 0)//has the slider changed and is it positive
{
Debug.Log("prevLED Changed");
if (prevLed < ledNumber.value)// am I removing or adding buttons
{
Debug.Log("Adding LED");
for (int x = 0; x < (int)ledNumber.value - prevLed; ++x)//for the difference in the number changed
{
for (int y = 0; y < IncrementsPerRotation.value; y++)//add a led to the top row
{
float angle = 360 / IncrementsPerRotation.value * y;// get angle
// if there isnt enough lists, add another one;
if(LedConfig.Count-1 < y)
{
LedConfig.Add(new List<button>());
++prevIncrements;
}
//object: LED Where: (see GetPos) What angle: angle converted to radians
LedConfig[y].Add(Instantiate(Led, GetPos(y, angle), new Quaternion(Quaternion.identity.x, Quaternion.identity.y, angle * (Mathf.PI / 180f), Quaternion.identity.w),canvas));
Debug.Log("got past instantiate");
}
++prevLed;
Debug.Log("end of outer for loop");
}
}
else
{
Debug.Log("Removing LED");
for (int x = 0; x < prevLed - (int)ledNumber.value; ++x)//for the difference in the number changed
{
for (int y = 0; y < LedConfig.Count; y++)//delete the top row of LEDs
{
LedConfig[y][LedConfig[y].Count - 1].delete();//delete the LED
LedConfig[y].RemoveAt(LedConfig[y].Count - 1);//remove it from the list
}
--prevLed;
Debug.Log("end of outer for loop");
}
}
}
if (prevIncrements != (int)IncrementsPerRotation.value && (int)IncrementsPerRotation.value > 0)
{
deleteAll();
prevLed = 0;
}
}
void deleteAll()
{
for (int x = 0; x < LedConfig.Count; ++x)//for the difference in the number changed
{
for (int y = 0; y < LedConfig[x].Count; y++)//delete the top row of LEDs
{
LedConfig[y][LedConfig[y].Count - (y + 1)].delete();//delete the LED
LedConfig[y].RemoveAt(LedConfig[y].Count - (y + 1));//remove it from the list
}
}
}
private Vector2 GetPos(int a,float angle)
{
float angleInRadians = angle * (Mathf.PI / 180f);
++a;
Debug.Log("x " + (buttonW * a) * (Mathf.Sin(angleInRadians) * 180 / Mathf.PI));
Debug.Log("y " + (buttonW * a) * (Mathf.Cos(angleInRadians) * 180 / Mathf.PI));
Debug.Log("middleX " + middleX);
Debug.Log("middleY " + middleY);
Debug.Log("tot X " + (middleX + buttonW * a * Mathf.Sin(angleInRadians)));
Debug.Log("tot Y " + (middleY + buttonW * a * Mathf.Cos(angleInRadians)));
return new Vector2(middleX + buttonW * a * Mathf.Sin(angleInRadians), middleY + buttonW * a * (Mathf.Cos(angleInRadians)));
}
The code is having many errors:
Moving the ledNumber creates multiple squares on the same spot
Moving the IncrementsPerRotations causes an index out of range error which pauses the game, if the game is continued (by pressing the pause button) the Fibonacci spiral is produced with the squares and the squares are at random angles.
This is not all the code, only the part which is related to the error.
Edit: Here is a visual aid of what the desired output should look like at increments per rotation values 1-4 and led number at 3

How can I calculate and create positions of triangle shape?

private void FormationTriangle()
{
newpositions = new List<Vector3>();
for (int x = 0; x < squadMembers.Count; x++)
{
for (int y = x; y < 2 * (squadMembers.Count - x) - 1; y++)
{
Vector3 position = new Vector3(x, y);
newpositions.Add(position);
}
}
move = true;
formation = Formation.Square;
}
The loops are wrong. It put the squadMembers in one line one above the other.
Not even close to a triangle shape.
I want the squadMembers to stand in a triangle shape.
This is the moving part: But the problem is with the loops calculating the triangle shape positions. Other formations I did are working fine.
private void MoveToNextFormation()
{
if (randomSpeed == false)
{
if (step.Length > 0)
step[0] = moveSpeed * Time.deltaTime;
}
for (int i = 0; i < squadMembers.Count; i++)
{
squadMembers[i].transform.LookAt(newpositions[i]);
if (randomSpeed == true)
{
squadMembers[i].transform.position = Vector3.MoveTowards(
squadMembers[i].transform.position, newpositions[i], step[i]);
}
else
{
squadMembers[i].transform.position = Vector3.MoveTowards(
squadMembers[i].transform.position, newpositions[i], step[0]);
}
if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) <
threshold)
{
if (squareFormation == true)
{
Vector3 degrees = new Vector3(0, 0, 0);
Quaternion quaternion = Quaternion.Euler(degrees);
squadMembers[i].transform.rotation = Quaternion.Slerp(
squadMembers[i].transform.rotation, quaternion,
rotateSpeed * Time.deltaTime);
}
else
{
squadMembers[i].transform.rotation = Quaternion.Slerp(
squadMembers[i].transform.rotation, quaternions[i],
rotateSpeed * Time.deltaTime);
}
}
}
}
This answer will produce a triangle arranged like this:
x
x x
x x x
x x x x
x x x x x
Or, if there aren't enough to fill a full triangle:
x
x x
x x x
x x x x
x x x
Since you aren't guaranteed a perfectly triangular number of units, you should overestimate how big your triangle is, keep count of how many units you have placed, and then quit placing them when you reach your limit.
First, find the height of the smallest triangular number greater than your number of units, and that triangular number itself:
int height = Mathf.CeilToInt( (Mathf.Sqrt(8*squadMembers.Count+1f)-1f)/2 )
int slots = (int)(height * (height+1f)/2f)
Then, find the position of the first unit. We need to know how many rows of slots we have and how wide the bottom row of slots is:
float verticalModifier = 0.8f; // 0.8f to decrease vertical space
float horizontalModifier = 1.25f; // 1.25f to increase horizontal space
float width = 0.5f * (height-1f);
Vector3 startPos = new Vector3(width* horizontalModifier, 0f, (float)(height-1f) * verticalModifier);
Then, add until you've added enough
int finalRowCount = height - slots + squadMembers.Count;
for (int rowNum = 0 ; rowNum < height && newpositions.Count < squadMembers.Count; rowNum++) {
for (int i = 0 ; i < rowNum+1 && newpositions.Count < squadMembers.Count ; i++ ) {
float xOffset = 0f;
if (rowNum+1 == height) {
// If we're in the last row, stretch it ...
if (finalRowCount !=1) {
// Unless there's only one item in the last row.
// If that's the case, leave it centered.
xOffset = Mathf.Lerp(
rowNum/2f,
-rowNum/2f,
i/(finalRowCount-1f)
) * horizontalModifier;
}
}
else {
xOffset = (i-rowNum /2f) * horizontalModifier;
}
float yOffset = (float)rowNum * verticalModifier;
Vector3 position = new Vector3(
startPos.x + xOffset, 0f, startPos.y - yOffset);
newpositions.Add(position);
}
}
Let's see what the list of positions contains for a simple value, n = 3
First, loop x from 0 to 2 (3 - 1)
Then for each x, loop from x to 4-x (3*2 - x - 1 - 1)
Remembering that a<b is the same as a<=b-1
That gives us...
0,0
0,1
0,2
0,3
0,4
1,1
1,2
1,3
2,2
Which is a lot of positions. Certainly more than 3 units can occupy! At least it is a triangle:
X\Y 0 1 2 3 4
0 # # # # #
1 # # #
2 #
The main problem is that you're generating way more positions than needed and expecting to fill it somehow.
You need to calculate your width and height based on the area formula for a triangle: A = (b*h)/2 and you may even want b=h, where A = number of units.
So, something like this:
int b = Mathf.CeilToInt(Mathf.Sqrt(squadMembers.Count));
for (int x = 0; x < b; x++)
{
//the divide by 2 is accounted for with this 2*
for (int y = x; y < 2 * (b - x) - 1; y++)
{
Vector3 position = new Vector3(x, y);
newpositions.Add(position);
}
}

OpenGL/SharpGL Faces Misbehaving

I am currently writing an OpenGL application using the SharpGL library and I am trying to simply create a 3x3x3 set of cubes arranged in a symmetric grid.
I am currently seeing some strange behaviour exhibited in the following picture:
This has me completely stumped as I can see no reason why the code is missing out the last 3 blocks. The method in charge of creating the cube looks like this:
private void CreateCube2(OpenGL gl, int cubeSize)
{
gl.PushMatrix();
const float spacing = 2.5f;
for (int z = 0; z < cubeSize; z++)
{
for (int y = 0; y < cubeSize; y++)
{
for (int x = 0; x < cubeSize; x++)
{
var cube = new Cube();
ColourCube(cube, cubeSize, x, y, z);
cube.Render(gl, RenderMode.Render);
gl.Translate(spacing, 0, 0);
}
gl.Translate(-spacing * cubeSize, spacing, 0);
}
gl.Translate(0, -spacing * cubeSize, spacing);
}
gl.PopMatrix();
}
where the definition of ColourCube is as follows:
private bool m_blackCubeMiddle = true;
private void ColourCube(Cube cube, int size, int x, int y, int z)
{
cube.Faces[0].Material = (!m_blackCubeMiddle || y == 0) ? WhiteMaterial : BlackMaterial; // Bottom
cube.Faces[1].Material = (!m_blackCubeMiddle || y == size - 1) ? YellowMaterial : BlackMaterial; // Top
cube.Faces[2].Material = (!m_blackCubeMiddle || x == size - 1) ? GreenMaterial : BlackMaterial; // Right
cube.Faces[3].Material = (!m_blackCubeMiddle || x == 0) ? BlueMaterial : BlackMaterial; // Left
cube.Faces[4].Material = (!m_blackCubeMiddle || z == 0) ? OrangeMaterial : BlackMaterial; // Front
cube.Faces[5].Material = (!m_blackCubeMiddle || z == size - 1) ? RedMaterial : BlackMaterial; // Back
}
The entire project can be downloaded from here.
The strange behaviour is caused by a bug in SharpGL 'Polygon.Render' method. It is not caused by your own code. When you call Triangulate on the cube, it already shows 27 cubes on screen in the correct positions. But even then, SharpGL incorrectly renders one of the cubes.
Having looked at the source code for ShapGL's Cube & Polygon classes I'ld suggest to write your own cube class. The implementation of the Cube class, that you are using now, is absolutely horible from several standpoints (GL_POLYGON (deprecated), immediate mode vertex submission (deprecated))

How to find number of pixels from specific color in an image?

So i'm trying to make a program that can find how many pixels of a specific colour it has in it. The images are pictures taken with camera and after that some areas on them has been marked on photoshop, and i need to find the exact number of this pixels. But i have few problems.
I'm using getPixel(x,y) but and i'm comparing to the Color.FromArgb(red, green, blue) that i want but... my first problem is that for colors differ a little for example i want to find out the color
RGB 116,110,40 but when you draw with this color on photoshop some pixels get a little diferent color like RGB 115,108,38 (and others similar) and i want to include this as well. So i finally came up with this code(but it seems that id does now work right):
public Form1()
{
InitializeComponent();
}
Bitmap image1;
int count=0;
int red, green, blue;
int redt, greent, bluet;
double reshenie;
private void button1_Click(object sender, EventArgs e)
{
try
{
red = int.Parse(textBox1.Text);
green = int.Parse(textBox2.Text);
blue = int.Parse(textBox3.Text);
// Retrieve the image.
image1 = new Bitmap(#"C:\bg-img.jpg", true);
double widht, height, pixel ;
int x, y;
MessageBox.Show(pixel.ToString());
// Loop through the images pixels
for (x = 0; x < image1.Width; x++)
{
for (y = 0; y < image1.Height; y++)
{
Color pixelColor = image1.GetPixel(x, y);
redt = pixelColor.R;
greent = pixelColor.G;
bluet = pixelColor.B;
if ((red+10>=redt) && (red-10>=redt))//i used +-10 in attempt to resolve the problem that i have writed about the close colours
{
if ((green + 10 >= greent) && (green - 10 >= greent))
{
if ((blue + 10 >= bluet) && (blue - 10 >= bluet))
{
count += 1;
}
}
}
}
}
pictureBox1.Image = image1;
MessageBox.Show("Imashe " + count.ToString());
count = 0;
}
catch (ArgumentException)
{
MessageBox.Show("There was an error." +
"Check the path to the image file.");
}
}
The problem is that i dont get the result that i expect. For example when i have to get like 1000 pixels i get more or less and i cant find where is my mistake. So if someone can give me idea what i'm doing wrong. Thanks for all the help in advance.
Try with this loop instead :
int epsilon = 10;
for (x = 0; x < image1.Width; ++x)
{
for (y = 0; y < image1.Height; ++y)
{
Color pixelColor = image1.GetPixel(x, y);
redt = pixelColor.R;
greent = pixelColor.G;
bluet = pixelColor.B;
if (Math.Abs(redt - red) <= epsilon &&
Math.Abs(greent - green) <= epsilon &&
Math.Abs(bluet - blue) <= epsilon)
{
++ count;
}
}
}
Where epsilon is the maximal difference between pixel color and targetted color, for each channel.
From your code:
if ((green + 10 >= greent) && (green - 10 >= greent))
If (a - 10 >= b), then for sure (a + 10 >= b). See if you can understand why.
I think you may have meant
if ((green - 10 <= greent) && (greent <= green + 10))
Ordering the condition like that helps with readability, because greent has to be between green - 10 and green + 10, and is also physically located between those expressions.
I think your color comparison is not right. You mixed the <= and >= in your attempt to be in a range around the color. Try this:
if ((red+10 >= redt) && (red-10 <= redt)) //i used +-10 in attempt to resolve the problem that i have writed about the close colours
{
if ((green + 10 >= greent) && (green - 10 <= greent))
{
if ((blue + 10 >= bluet) && (blue - 10 <= bluet))
{
count += 1;
}
}
}

Categories