I am creating a class with specific number of objects.When these objects are created and drawn on screen with that capacity again I reinitialize that class.The problem is that I want to reinitialize in such a way that if new objects are created then previous must be persist/drawn on the screen.I am not able to get the logic.
crShade = new CreateShade[Obj_num]; for (int i = incr_Obj; i < crShade.Length; i++) {
int r = rad.Next(0, 7); int x = 0; switch (r) {
case 0: x = 0; break; case 1: x = 120; break; case 2: x = 240; break; case 3: x = 360; break;
}
X_pos.Add(x); crShade[i] = new CreateShade(x, -60, clr[3]); _Shade.Add(crShade[i]);
}
--
public class CreateShade {
public int posX; public int posY; public Color color; Random r = new Random(); private int width = 120; private int height = 60; public static bool _Fall; public static bool check; public static List<int> y_pos = new List<int>(); int balance = 0; public CreateShade(int x, int y, Color color) {
int random = r.Next(0, 4); this.posY = y; this.posX = x; this.color = color;
}
public void draw(SpriteBatch batch) {
batch.Draw(Vimap_ScreenManager.blank, new Rectangle(posX, posY, width, height), color);
}
public void update() {
int counter = 0; if (posY != 740-balance) {
posY += 10; if (counter != y_pos.Count) {
if (new Rectangle(posX, posY, 120, 60).Intersects(new Rectangle(VimapGamePage.X_pos.ElementAt(counter), y_pos.ElementAt(counter), 120, 60))) {
balance = counter * 60;
}
else {
counter++;
}
}
//check = true;
}
else {
y_pos.Add(posY); _Fall = true; // VimapGamePage.End_Reach = true;
}
}
public void Move_X(Point p) {
if (p.X <= 240) {
if (p.X >= 0 && p.X <= 120) {
posX = 0;
}
else if (p.X > 120 && p.X <= 240) {
posX = 120;
}
}
else if (p.X > 240) {
if (p.X > 240 && p.X <= 360) {
posX = 240;
}
else if (p.X > 360 && p.X <= 480) {
posX = 360;
}
}
}
}
Related
I am trying to develop a program using OpenTK. The purpose of this program is to load a STL (stereolithography) file in ASCII format, then render it in OpenTK, and keep track of the selected object using name stack. In this program, I use the mouse right click to get the selected object.
The brief explanation of STL file is here:
https://en.wikipedia.org/wiki/STL_(file_format)
In my code, I am using 2 STL files. The first STL file is a simple geometry (file size 8 kb). The second STL file is a complex geometry (file size 1167 kb). When I used the first STL file and run my code, it just worked fine when I use my mouse right click function.
However, when I used second STL file and run my code (follow by mouse right click), I got this Fatal Execution Engine Error Exception. I am not sure why I get this error. Is it because of the file size is too big? But I can render this second file into OpenTK. Is it because I have to set a large enough buff size here to avoid this exception?
Do you have any idea why this is happening? Is there any method to avoid this error/exception?
The link for these two STL files are here:
https://drive.google.com/drive/folders/1v9bUzqVx1a1_KbnSXCQ5LREoQaAFUn2D?usp=sharing
Here are my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
namespace OpenTK3D
{
public class Game3D
{
private GameWindow window;
private float zoom;
private bool hasRotationStarted;
private int startX;
private int startY;
private float xRotAngle;
private float yRotAngle;
private bool hasPanningStarted;
private float xTrans;
private float yTrans;
private int BUFSIZE = 512;
private string filePath = #"C:\Users\mpelmt\Desktop\ISF forming direction optimization\verify_65_40_yForming_noFlange.STL";
private double angleLimit = 60;
public Game3D(GameWindow wd)
{
this.window = wd;
var zBoundary = zBoundaryValue(filePath);
hasRotationStarted = false;
startX = 0;
startY = 0;
xRotAngle = 28;
yRotAngle = -45;
zoom = -(float)zBoundary;
hasPanningStarted = false;
xTrans = 0;
yTrans = 0;
start();
}
public void start()
{
window.Load += loaded;
window.Resize += resize;
window.RenderFrame += renderFrame;
window.MouseDown += mouseLeftPress;
window.MouseUp += mouseRelease;
window.MouseMove += mouseDragEvent;
window.MouseWheel += MouseWheelHandler;
window.MouseDown += wheelPressEvent;
window.MouseUp += wheelReleaseEvent;
window.MouseMove += wheelDragEvent;
window.MouseDown += select;
window.Run(1.0 / 60.0);
}
private List<double> getAllSTLData(string path)
{
string[] text = System.IO.File.ReadAllLines(path);
List<double> allData = new List<double>();
foreach (var line in text)
{
if (line.Contains("facet normal"))
{
var normal = Array.ConvertAll(line.Remove(0, 16).Split(' '), double.Parse);
allData.AddRange(normal);
}
if (line.Contains("vertex"))
{
var position = Array.ConvertAll(line.Remove(0, 16).Split(' '), double.Parse);
allData.AddRange(position);
}
}
return allData;
}
private Dictionary<int, List<double>> getAllFacets(string path)
{
var allSTLData = getAllSTLData(path);
var allFacet = new Dictionary<int, List<double>>();
for (int i = 0; i < (allSTLData.Count) / 12; i++)
{
allFacet.Add(i + 1, allSTLData.GetRange(12 * i, 12));
}
return allFacet;
}
private double yBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfY = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfY.Add(vertex[1]);
listOfY.Add(vertex[4]);
listOfY.Add(vertex[7]);
}
return listOfY.Max() - listOfY.Min();
}
private double xBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfX = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfX.Add(vertex[0]);
listOfX.Add(vertex[3]);
listOfX.Add(vertex[6]);
}
return listOfX.Max() - listOfX.Min();
}
private double zBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfZ = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfZ.Add(vertex[2]);
listOfZ.Add(vertex[5]);
listOfZ.Add(vertex[8]);
}
return listOfZ.Max() - listOfZ.Min();
}
private List<double> getAngleRangeWithinLimit(double angleLimit)
{
var result = new List<double>();
var section = (int)angleLimit / 5;
var remain = angleLimit % 5;
for (int i = 0; i < section; i++)
{
result.Add(5 * i);
result.Add(5 * i + 5);
}
if (remain != 0)
{
result.Add(result.Last());
result.Add(result.Last() + remain);
}
return result;
}
public Dictionary<int, List<double>> pickSelectFacetsByAngleInYForm(string path, double angleLimit)
{
var result = new Dictionary<int, List<double>>();
var allFacets = getAllFacets(path);
var angleRange = getAngleRangeWithinLimit(angleLimit);
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var data = kp.Value;
var id = kp.Key;
var tempList = new List<double>();
var angle = Math.Acos(Math.Abs(data[1])) * 180 / (Math.PI);
for (int i = 0; i < angleRange.Count / 2; i++)
{
if (angle >= angleLimit)
{
tempList.AddRange(data);
tempList.Add(angleLimit + 1);
break;
}
else if (angle >= angleRange[2 * i] && angle <= angleRange[2 * i + 1])
{
tempList.AddRange(data);
tempList.Add(angleRange[2 * i + 1]);
break;
}
}
result.Add(id, tempList);
}
return result;
}
public void renderColorPlotYForm(string path, double angleLimit)
{
var plotData = pickSelectFacetsByAngleInYForm(path, angleLimit);
foreach (KeyValuePair<int, List<double>> kv in plotData)
{
var id = kv.Key;
var data = kv.Value;
GL.Begin(BeginMode.Triangles);
var colorRange = data.Last();
if (colorRange == 5)
{
// green
GL.Color3(0.0, 1.0, 0.0);
}
if (colorRange == angleLimit + 1)
{
//red
GL.Color3(1.0, 0.0, 0.0);
}
if (colorRange == 30)
{
// yellow
GL.Color3(1.0, 1.0, 0.0);
}
if (colorRange < 30 && colorRange > 5)
{
var diff = 30 - colorRange;
var ratio = diff / 25;
GL.Color3(1 - ratio, 1, 0);
}
if (colorRange > 30 && colorRange < angleLimit + 1)
{
var ratio = (angleLimit - colorRange) / angleLimit;
GL.Color3(1, 1 - ratio, 0);
}
var listOfVertex = data.GetRange(3, 9);
for (int i = 0; i < 3; i++)
{
var vertex = listOfVertex.GetRange(3 * i, 3);
GL.Vertex3(vertex[0], vertex[1], vertex[2]);
}
GL.End();
}
}
public void pickSelectColorPlotYForm(string path, double angleLimit)
{
var plotData = pickSelectFacetsByAngleInYForm(path, angleLimit);
foreach (KeyValuePair<int, List<double>> kv in plotData)
{
var id = kv.Key;
var data = kv.Value;
GL.LoadName(id);
GL.Begin(BeginMode.Triangles);
var colorRange = data.Last();
if (colorRange == 5)
{
// green
GL.Color3(0.0, 1.0, 0.0);
}
if (colorRange == angleLimit + 1)
{
//red
GL.Color3(1.0, 0.0, 0.0);
}
if (colorRange == 30)
{
// yellow
GL.Color3(1.0, 1.0, 0.0);
}
if (colorRange < 30 && colorRange > 5)
{
var diff = 30 - colorRange;
var ratio = diff / 25;
GL.Color3(1 - ratio, 1, 0);
}
if (colorRange > 30 && colorRange < angleLimit + 1)
{
var ratio = (angleLimit - colorRange) / angleLimit;
GL.Color3(1, 1 - ratio, 0);
}
var listOfVertex = data.GetRange(3, 9);
for (int i = 0; i < 3; i++)
{
var vertex = listOfVertex.GetRange(3 * i, 3);
GL.Vertex3(vertex[0], vertex[1], vertex[2]);
}
GL.End();
}
}
public void loaded(object o, EventArgs e)
{
GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL.Enable(EnableCap.DepthTest);
}
public void renderFrame(object o, EventArgs e)
{
var xBoundary = xBoundaryValue(filePath);
var yBoundary = yBoundaryValue(filePath);
var zBoundary = zBoundaryValue(filePath);
var xCen = xBoundary / 2;
var yCen = yBoundary / 2;
var zCen = zBoundary / 2;
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Translate(xTrans, yTrans, zoom*3);
GL.Rotate(xRotAngle, 1.0, 0, 0);
GL.Rotate(yRotAngle, 0, 1, 0);
renderColorPlotYForm(filePath, angleLimit);
window.SwapBuffers();
}
public void resize(object o, EventArgs e)
{
var zBoundary = zBoundaryValue(filePath);
GL.Viewport(0, 0, window.Width, window.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
// the fov must be radian
var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f*(MathHelper.Pi)/180, window.Width / window.Height, 1.0f, (float)zBoundary * (float)zBoundary);
GL.LoadMatrix(ref matrix);
GL.MatrixMode(MatrixMode.Modelview);
}
private void processHits(int hits, int[] buffer)
{
Console.WriteLine("hit: {0}", hits);
if (hits > 0)
{
int choose = buffer[3];
int depth = buffer[1];
for (int i = 0; i < hits; i++)
{
if (buffer[i * 4 + 1] < depth)
{
choose = buffer[i * 4 + 3];
depth = buffer[i * 4 + 1];
}
}
Console.WriteLine("choosen: {0}", choose);
}
}
private void GluPickMatrix(double x, double y, double deltax, double deltay, int[] viewport)
{
if (deltax <= 0 || deltay <= 0)
{
return;
}
GL.Translate((viewport[2] - 2 * (x - viewport[0])) / deltax, (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
GL.Scale(viewport[2] / deltax, viewport[3] / deltay, 1.0);
}
public void select(object o, MouseEventArgs e)
{
var zBoundary = zBoundaryValue(filePath);
var mouse = Mouse.GetState();
if (mouse[MouseButton.Right])
{
var buffer = new int[BUFSIZE];
var viewPort = new int[4];
int hits;
GL.GetInteger(GetPName.Viewport, viewPort);
GL.SelectBuffer(BUFSIZE, buffer);
GL.RenderMode(RenderingMode.Select);
GL.InitNames();
GL.PushName(0);
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
GluPickMatrix(e.Mouse.X, viewPort[3] - e.Mouse.Y, 5.0, 5.0, viewPort);
var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f * (MathHelper.Pi) / 180, window.Width / window.Height, 1.0f, (float)zBoundary * (float)zBoundary);
GL.MultMatrix(ref matrix);
GL.MatrixMode(MatrixMode.Modelview);
pickSelectColorPlotYForm(filePath, angleLimit);
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
GL.Flush();
hits = GL.RenderMode(RenderingMode.Render);
processHits(hits, buffer);
}
}
public void mouseLeftPress(object sender, MouseEventArgs e)
{
if (e.Mouse.LeftButton == ButtonState.Pressed)
{
hasRotationStarted = true;
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void mouseRelease(object sender, MouseEventArgs e)
{
if (e.Mouse.LeftButton == ButtonState.Released)
{
hasRotationStarted = false;
}
}
public void mouseDragEvent(object sender, MouseEventArgs e)
{
if (hasRotationStarted == true && e.Mouse.X != e.Mouse.Y)
{
xRotAngle = xRotAngle + (e.Mouse.Y - startY);
yRotAngle = yRotAngle + (e.Mouse.X - startX);
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void MouseWheelHandler(object sender, MouseWheelEventArgs e)
{
var xBoundary = xBoundaryValue(filePath);
if (e.Delta > 0)
{
zoom += 0.1f * (float)xBoundary;
}
if (e.Delta < 0)
{
zoom -= 0.1f * (float)xBoundary;
}
}
public void wheelPressEvent(object sender, MouseEventArgs e)
{
if (e.Mouse.MiddleButton == ButtonState.Pressed)
{
hasPanningStarted = true;
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void wheelReleaseEvent(object sender, MouseEventArgs e)
{
if (e.Mouse.MiddleButton == ButtonState.Released)
{
hasPanningStarted = false;
}
}
public void wheelDragEvent(object sender, MouseEventArgs e)
{
if (hasPanningStarted == true)
{
xTrans = xTrans + 2 * (e.Mouse.X - startX);
yTrans = yTrans - 2 * (e.Mouse.Y - startY);
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
}
}
Here is the main function:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
namespace OpenTK3D
{
class Program
{
static void Main(string[] args)
{
var window = new GameWindow(500, 500);
var gm = new Game3D(window);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Press enter to finish...");
Console.ReadLine();
}
}
}
This is the result when I run my code using the first STL file (it works fine):
When I run my code using the second STL file, I got this Fatal Execution Engine Error:
I am following this tutorial: https://www.youtube.com/watch?v=LyV7cEQyZMk to generate a planet for my game. I have gotten up to 6:08
For some reason, the color of the planet won't change depending on the type like it should, it is only white.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Type
{
Water, Ice, Volcano, Snow, Grass, Forest, Desert, Rocky
}
[CreateAssetMenu()]
public class PlanetSettings : ScriptableObject
{
public float Size;
public Type type;
}
public class TerrainFace
{
Mesh mesh;
int resolution;
Vector3 localUp;
Vector3 axisA;
Vector3 axisB;
Vector3[] vertices;
int[] triangles;
PlanetSettings settings;
Vector3 CalculatePointOnPlanet(Vector3 p)
{
return p * settings.Size;
}
public TerrainFace(Mesh mesh, int resolution, Vector3 localUp, PlanetSettings settings)
{
this.mesh = mesh;
this.resolution = resolution;
this.localUp = localUp;
this.settings = settings;
axisA = new Vector3(localUp.y, localUp.z, localUp.x);
axisB = Vector3.Cross(localUp, axisA);
}
public void ConstructMesh()
{
vertices = new Vector3[resolution * resolution];
triangles = new int[(resolution - 1) * (resolution - 1) * 6];
int triIndex = 0;
for (int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
int index = x + y * resolution;
Vector2 percent = new Vector2(x, y) / (resolution - 1);
Vector3 pointOnUnitCube = localUp + (percent.x - 0.5f) * 2 * axisA + (percent.y - 0.5f) * 2 * axisB;
Vector3 pointOnUnitSphere = pointOnUnitCube.normalized;
vertices[index] = CalculatePointOnPlanet(pointOnUnitSphere);
if (x != resolution - 1 && y != resolution - 1)
{
triangles[triIndex] = index;
triangles[triIndex + 1] = index + resolution + 1;
triangles[triIndex + 2] = index + resolution;
triangles[triIndex + 3] = index;
triangles[triIndex + 4] = index + 1;
triangles[triIndex + 5] = index + resolution + 1;
triIndex += 6;
}
}
}
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
public class PlanetGenerator : MonoBehaviour
{
[Range(2, 256)]
public int Resolution = 10;
public PlanetSettings Settings;
[SerializeField, HideInInspector]
MeshFilter[] meshFilters;
TerrainFace[] terrainFaces;
Color c;
private void OnValidate()
{
GeneratePlanet();
}
void Initialize()
{
switch (Settings.type)
{
case Type.Desert:
c = new Color(244, 176, 66, 255);
break;
case Type.Forest:
c = new Color(9, 119, 22, 255);
break;
case Type.Grass:
c = new Color(21, 193, 41, 255);
break;
case Type.Ice:
c = new Color(105, 206, 239, 255);
break;
case Type.Rocky:
c = new Color(104, 65, 6, 255);
break;
case Type.Snow:
c = new Color(204, 226, 229, 255);
break;
case Type.Volcano:
c = new Color(160, 16, 16, 255);
break;
case Type.Water:
c = new Color(26, 69, 178, 255);
break;
default:
c = new Color();
break;
}
if (meshFilters == null || meshFilters.Length == 0)
meshFilters = new MeshFilter[6];
terrainFaces = new TerrainFace[6];
Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back };
for (int i = 0; i < 6; i++)
{
if (meshFilters[i] == null)
{
GameObject meshObj = new GameObject("mesh");
meshObj.transform.parent = transform;
meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
meshFilters[i] = meshObj.AddComponent<MeshFilter>();
meshFilters[i].sharedMesh = new Mesh();
}
terrainFaces[i] = new TerrainFace(meshFilters[i].sharedMesh, Resolution, directions[i], Settings);
}
}
public void GeneratePlanet()
{
Initialize();
GenerateMesh();
GenerateColor();
}
void GenerateMesh()
{
foreach (TerrainFace face in terrainFaces)
{
face.ConstructMesh();
}
}
void GenerateColor()
{
foreach (MeshFilter m in meshFilters)
{
m.GetComponent<MeshRenderer>().sharedMaterial.color = c;
}
}
}
The size part works, it's just the color that doesn't. I should see a dark red colored sphere. I have been trying different things to identify the problem, I think i have narrowed it down to sharedmaterial.color but I don't know for sure.
Well you don't have the code he talks about at around the 5 min mark where he changed the TerrainFace object and it's constructor.
I'am trying to Draw a Triangle in through three points, with known coordinates enclosed within the Triangle.
I wrote this algorithm to do all this, but the code is slow.
Can anyone give me another easy and faster way to draw a Triangle?
I have got the algorithm of drawing the line from this site but do not mention the post sorry.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
public partial class Form1 : Form
{
int Screen_height;
int Screen_width;
List<int> Pointsx = new List<int>(new int[] { });
List<int> Pointsy = new List<int>(new int[] { });
List<int> edge_one_Tranglex= new List<int>(new int[] { });
List<int> edge_one_Trangley = new List<int>(new int[] { });
List<int> edge_two_Tranglex = new List<int>(new int[] { });
List<int> edge_two_Trangley = new List<int>(new int[] { });
List<int> edge_three_Tranglex = new List<int>(new int[] { });
List<int> edge_three_Trangley = new List<int>(new int[] { });
int edge = 1;
Bitmap bmp;
int start = 0;
int center_x;
int center_y;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Screen_height = panel1.Height;
Screen_width = panel1.Width;
Console.WriteLine(" " + Screen_height + "," + Screen_width);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (start == 0)
{
var sw = new Stopwatch();
sw.Start();
bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.BackgroundImage = (Image)bmp;
panel1.BackgroundImageLayout = ImageLayout.None;
//from x to x2 and from y to y2
//D_line(100, 10, -100, 20);
D_Triangle(-300, 10, 100, 20, 100, -100);
sw.Stop();
Console.WriteLine("" + sw.Elapsed);
start += 1;
}
}
public void D_line(int x, int y, int x2, int y2)
{
center_x = Screen_width / 2;
center_y = Screen_height / 2;
line(center_x + x, center_y - y, center_x + x2, center_y - y2);
}
public void line(int x, int y, int x2, int y2)
{
int w = x2 - x;
int h = y2 - y;
int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1;
if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1;
if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1;
int longest = Math.Abs(w);
int shortest = Math.Abs(h);
if (!(longest > shortest))
{
longest = Math.Abs(h);
shortest = Math.Abs(w);
if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
dx2 = 0;
}
int numerator = longest >> 1;
for (int i = 0; i <= longest; i++)
{
//putpixel(x, y, color);
bmp.SetPixel(x, y, Color.Red);
//my code
if (edge == 1)
{
edge_one_Tranglex.Add(x);
edge_one_Trangley.Add(y);
}
if (edge == 2)
{
edge_two_Tranglex.Add(x);
edge_two_Trangley.Add(y);
}
if (edge == 3)
{
edge_three_Tranglex.Add(x);
edge_three_Trangley.Add(y);
}
if (edge >= 4)
{
if (!Pointsx.Contains(x) || !Pointsy.Contains(y))
{
Pointsx.Add(x);
Pointsy.Add(y);
}
}
numerator += shortest;
if (!(numerator < longest))
{
numerator -= longest;
x += dx1;
y += dy1;
}
else
{
x += dx2;
y += dy2;
}
}
edge++;
// edge_two_Trangle.ForEach(p => Console.WriteLine(p));
}
void D_Triangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
D_line(x1, y1, x2, y2);
D_line(x2, y2, x3, y3);
D_line(x3, y3, x1, y1);
int a = edge_two_Tranglex.Count();
for(int i =1; i < a -1;)
{
line(center_x + x1, center_y - y1, edge_two_Tranglex[i], edge_two_Trangley[i]);
i++;
}
}
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I have translated the code from javascript to c# which can be found by going to this excellent demo at http://fractal.qfox.nl/dragon.js
My translation is intended to produce just a single dragon upon clicking the button but I think I have missed something in my version.
See the Wikipedia article: Dragon Curve for more information.
Incomplete dragon fractal output:
Code:
public partial class MainPage : UserControl
{
PointCollection pc;
Int32[] pattern = new Int32[] { 1, 1, 0, 2, 1, 0, 0, 3 };
Int32[] position = new Int32[] { 0, 0, 0, 0, 0, 0, 0, 0 };
Boolean toggle;
Char r = default(Char);
Int32 distance = 10; // line length
Int32 step = 100; // paints per step
Int32 skip = 10; // folds per paint
Double x = 0;
Double y = 0;
Int32 a = 90;
public MainPage()
{
InitializeComponent();
}
private void btnFire_Click(object sender, RoutedEventArgs e)
{
x = canvas.ActualWidth / 3;
y = canvas.ActualHeight / 1.5;
pc = new PointCollection();
var n = step;
while (--n > 0)
{
List<Char> s = getS(skip);
draw(s);
}
Polyline p = new Polyline();
p.Stroke = new SolidColorBrush(Colors.Red);
p.StrokeThickness = 0.5;
p.Points = pc;
canvas.Children.Add(p);
}
List<Char> getS(Int32 n)
{
List<Char> s1 = new List<Char>();
while (n-- > 0) s1.Add(getNext(0));
return s1;
}
void draw(List<Char> s)
{
pc.Add(new Point(x, y));
for (Int32 i = 0, n = s.Count; i < n; i++)
{
pc.Add(new Point(x, y));
Int32 j;
if (int.TryParse(s[i].ToString(), out j) && j != 0)
{
if ((a + 90) % 360 != 0)
{
a = (a + 90) % 360;
}
else
{
a = 360; // Right
}
}
else
{
if (a - 90 != 0)
{
a = a - 90;
}
else
{
a = 360; // Right
}
}
// new target
if (a == 0 || a == 360)
{
y -= distance;
}
else if (a == 90)
{
x += distance;
}
else if (a == 180)
{
y += distance;
}
else if (a == 270)
{
x -= distance;
}
// move
pc.Add(new Point(x, y));
}
}
Char getNext(Int32 n)
{
if (position[n] == 7)
{
r = getNext(n + 1);
position[n] = 0;
}
else
{
var x = position[n] > 0 ? pattern[position[n]] : pattern[0];
switch (x)
{
case 0:
r = '0';
break;
case 1:
r = '1';
break;
case 2:
if (!toggle)
{
r = '1';
}
else
{
r = '0';
}
toggle = !toggle;
break;
}
position[n] = position[n] + 1;
}
return r;
}
}
I cleaned up the code, and tried to get how the pattern and position arrays should work to produce the correct sequence, but I couldn't figure it out. The last item in the pattern array is for example never used...
There is however a simpler method implementing the getNext method using just a counter:
bool getNext() {
cnt++;
return (cnt & ((cnt & -cnt) << 1)) != 0;
}
I have used that method before (about 20 years ago), and I found this implementation on the dragon curve wikipedia page.
The cleaned up code with this getNext implementation looks like this:
public partial class MainPage : UserControl {
PointCollection pc;
int cnt = 0;
int distance = 10; // line length
int steps = 1024; // number of paints
int x = 0;
int y = 0;
int a = 90;
public MainPage() {
InitializeComponent();
}
private void btnFire_Click(object sender, RoutedEventArgs e) {
x = (int)(canvas.ActualWidth / 3);
y = (int)(canvas.ActualHeight / 1.5);
pc = new PointCollection();
draw(getS(steps));
Polyline p = new Polyline();
p.Stroke = new SolidColorBrush(Colors.Red);
p.StrokeThickness = 0.5;
p.Points = pc;
canvas.Children.Add(p);
}
List<bool> getS(int n) {
List<bool> s1 = new List<bool>();
while (n-- > 0) {
s1.Add(getNext());
}
return s1;
}
void draw(List<bool> s) {
pc.Add(new Point(x, y));
foreach (bool z in s) {
a = (a + (z ? 90 : 270)) % 360;
// new target
switch (a) {
case 90: x += distance; break;
case 180: y += distance; break;
case 270: x -= distance; break;
default: y -= distance; break;
}
// move
pc.Add(new Point(x, y));
}
}
bool getNext() {
cnt++;
return (cnt & ((cnt & -cnt) << 1)) != 0;
}
}
My problem is that clicks only get registers on the lower right corner and in some cases not even there it seems to get worse the longer you stray from the 0.0 and the likes the worse it gets.
public void Render(SpriteBatch B, Camera C)
{
Vector2 firstSquare = new Vector2(C.Position.X / 32, C.Position.Y / 32);
int firstX = (int)firstSquare.X;
int firstY = (int)firstSquare.Y;
Vector2 squareOffset = new Vector2(C.Position.X % 32, C.Position.Y % 32);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 26; x++)
{
Tile T = GetTile(x + firstX, y + firstY);
if (T == null)
{
continue;
}
T.RenderWithCamera(B,new Vector2((x*32)-offsetX,(y*32)-offsetY));
}
}
public void CheckClick(float mx, float my,Camera C)
{
Vector2 firstSquare = new Vector2(C.Position.X / 32, C.Position.Y / 32);
int x = (int)firstSquare.X;
int y = (int)firstSquare.Y;
Vector2 squareOffset = new Vector2(C.Position.X % 32, C.Position.Y % 32);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;
int vx = (int)mx / 32;
int vy = (int)my / 32;
float x1 = vx + x;
float y1 = vy + y;
int maxX, maxY;
maxX = C.Width / 32;
maxY = C.Height / 32;
Console.WriteLine("MAX_X:" + maxX + "MAX_Y:" + maxY);
Tile T = GetTile(x1, y1);
Rectangle A = new Rectangle((int)mx, (int)my, 1, 1);
if (T == null)
{ Console.WriteLine("No Tile found"); return; }
if (T.IsInside(A))
{
Console.WriteLine("Not inside?");
Tile S = null;
S = new Wall((int)x1, (int)y1, 0);
if (S != null)
{
tiles.Add(S);
tiles2[(int)T.pos.X, (int)T.pos.Y] = S;
}
}
Console.WriteLine("Clicked Tile at X:" + T.pos.X + "Y:" + T.pos.Y);
}
public bool IsInside(Rectangle B) // TILE
{
Rectangle rectA = new Rectangle((int)Last_pos.X, (int)Last_pos.Y, icon.Width, icon.Height);
Console.WriteLine("A:" + rectA.X + "A.y:" + rectA.Y + "B.X:" + B.X + "B.Y:" + B.Y);
if(rectA.Intersects(B))
{
return true;
}
else
return false;
}
Here's how I like to handle clicking a tilemap.
int xTile = Math.floor((Mouse.X + CameraBounds.left) / Tile.width);
int yTile = Math.floor((Mouse.Y + CameraBounds.top) / Tile.height);