How to correct weird projection flickering? c# - c#
I have created a spinning cube and it's working fine except the weird flickering caused by clearing the picturebox.
This is my first 3D project and I have 0 experience in this.
I have recreated javidx9's code in c#
c# Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using static System.Math;
using static _3DTutorial1.Form1.Tools1;
namespace _3DTutorial1
{
public partial class Form1 : Form
{
private static PictureBox pictureBox1 = new PictureBox();
private static mesh meshCube;
//Projection Matrix
private static matrix4x4 matrixProjection;
private static float fNear = 0.1f;
private static float fFar = 1000;
private static float fFov = 90;
private static float fAspectRatio = (float)1000 / 1000;//Height / Width;
private static float fFovRad = 1 / (float)Tan(fFov * 0.5 / 180 * PI);
//Rotation
private static float fTheta = 0;
private static matrix4x4 matrixRotationZ;
private static matrix4x4 matrixRotationX;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Width = 1000;
Height = 1000;
pictureBox1.Dock = DockStyle.Fill;
pictureBox1.BackColor = Color.Black;
Controls.Add(pictureBox1);
timer1.Interval = 20;
meshCube = Create_mesh(
//SOUTH
Create_triangle(Create_vector3d(0, 0, 0), Create_vector3d(0, 1, 0), Create_vector3d(1, 1, 0)),
Create_triangle(Create_vector3d(0, 0, 0), Create_vector3d(1, 1, 0), Create_vector3d(1, 0, 0)),
//EAST
Create_triangle(Create_vector3d(1, 0, 0), Create_vector3d(1, 1, 0), Create_vector3d(1, 1, 1)),
Create_triangle(Create_vector3d(1, 0, 0), Create_vector3d(1, 1, 1), Create_vector3d(1, 0, 1)),
//NORTH
Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(1, 1, 1), Create_vector3d(0, 1, 1)),
Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 1, 1), Create_vector3d(0, 0, 1)),
//WEST
Create_triangle(Create_vector3d(0, 0, 1), Create_vector3d(0, 1, 1), Create_vector3d(0, 1, 0)),
Create_triangle(Create_vector3d(0, 0, 1), Create_vector3d(0, 1, 0), Create_vector3d(0, 0, 0)),
//TOP
Create_triangle(Create_vector3d(0, 1, 0), Create_vector3d(0, 1, 1), Create_vector3d(1, 1, 1)),
Create_triangle(Create_vector3d(0, 1, 0), Create_vector3d(1, 1, 1), Create_vector3d(1, 1, 0)),
//BOTTOM
Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 0, 1), Create_vector3d(0, 0, 0)),
Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 0, 0), Create_vector3d(1, 0, 0))
);
//Projection Matrix
matrixProjection = Create_matrix4x4(
(0, 0, fAspectRatio * fFovRad),
(1, 1, fFovRad),
(2, 2, fFar / (fFar - fNear)),
(3, 2, (-fFar * fNear) / (fFar - fNear)),
(2, 3, 1),
(3, 3, 0)
);
}
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.X)
{
timer1.Start();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Graphics g = pictureBox1.CreateGraphics();
//Rotation
fTheta += 0.01f;
matrixRotationZ = Create_matrix4x4(
(0, 0, (float)Cos(fTheta)),
(0, 1, (float)Sin(fTheta)),
(1, 0, (float)-Sin(fTheta)),
(1, 1, (float)Cos(fTheta)),
(2, 2, 1),
(3, 3, 1)
);
matrixRotationX = Create_matrix4x4(
(0, 0, 1),
(1, 1, (float)Cos(fTheta)),
(1, 2, (float)Sin(fTheta)),
(2, 1, (float)-Sin(fTheta)),
(2, 2, (float)Cos(fTheta)),
(3, 3, 1)
);
//Clear / Draw
List<triangle> Ready2DrawCube = new List<triangle>();
//Calculate Draw
foreach (var item in meshCube.tris)
{
triangle triangleProjected, triangleTranslated, triangleRotatedZ, triangleRotatedZX;
triangleRotatedZ = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d());
triangleRotatedZX = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d());
triangleProjected = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d());
triangleRotatedZ.p[0] = MultiplyMatrixVector(item.p[0], matrixRotationZ);
triangleRotatedZ.p[1] = MultiplyMatrixVector(item.p[1], matrixRotationZ);
triangleRotatedZ.p[2] = MultiplyMatrixVector(item.p[2], matrixRotationZ);
triangleRotatedZX.p[0] = MultiplyMatrixVector(triangleRotatedZ.p[0], matrixRotationX);
triangleRotatedZX.p[1] = MultiplyMatrixVector(triangleRotatedZ.p[1], matrixRotationX);
triangleRotatedZX.p[2] = MultiplyMatrixVector(triangleRotatedZ.p[2], matrixRotationX);
triangleTranslated = triangleRotatedZX;
triangleTranslated.p[0].z = triangleRotatedZX.p[0].z + 3.0f;
triangleTranslated.p[1].z = triangleRotatedZX.p[1].z + 3.0f;
triangleTranslated.p[2].z = triangleRotatedZX.p[2].z + 3.0f;
triangleProjected.p[0] = MultiplyMatrixVector(triangleTranslated.p[0], matrixProjection);
triangleProjected.p[1] = MultiplyMatrixVector(triangleTranslated.p[1], matrixProjection);
triangleProjected.p[2] = MultiplyMatrixVector(triangleTranslated.p[2], matrixProjection);
//Scale into view
triangleProjected.p[0].x += 1; triangleProjected.p[0].y += 1;
triangleProjected.p[1].x += 1; triangleProjected.p[1].y += 1;
triangleProjected.p[2].x += 1; triangleProjected.p[2].y += 1;
triangleProjected.p[0].x *= 0.5f * Width; triangleProjected.p[0].y *= 0.5f * Width;
triangleProjected.p[1].x *= 0.5f * Width; triangleProjected.p[1].y *= 0.5f * Width;
triangleProjected.p[2].x *= 0.5f * Width; triangleProjected.p[2].y *= 0.5f * Width;
//Done
Ready2DrawCube.Add(triangleProjected);
}
//Draw Triangles
g.Clear(Color.Black);
foreach (var item in Ready2DrawCube)
{
DrawTriangle(
(int)item.p[0].x, (int)item.p[0].y,
(int)item.p[1].x, (int)item.p[1].y,
(int)item.p[2].x, (int)item.p[2].y,
Pens.White
);
}
}
public class Tools1
{
private static Graphics g = pictureBox1.CreateGraphics();
public static void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, Pen p)
{
g.DrawLine(p, new Point(x1, y1), new Point(x2, y2));
g.DrawLine(p, new Point(x2, y2), new Point(x3, y3));
g.DrawLine(p, new Point(x3, y3), new Point(x1, y1));
}
public static vector3d MultiplyMatrixVector(vector3d _i, matrix4x4 _m)
{
vector3d o_ = Create_vector3d();
o_.x = _i.x * _m.m[0, 0] + _i.y * _m.m[1, 0] + _i.z * _m.m[2, 0] + _m.m[3, 0];
o_.y = _i.x * _m.m[0, 1] + _i.y * _m.m[1, 1] + _i.z * _m.m[2, 1] + _m.m[3, 1];
o_.z = _i.x * _m.m[0, 2] + _i.y * _m.m[1, 2] + _i.z * _m.m[2, 2] + _m.m[3, 2];
float w = _i.x * _m.m[0, 3] + _i.y * _m.m[1, 3] + _i.z * _m.m[2, 3] + _m.m[3, 3];
if (w != 0)
{
o_.x /= w;
o_.y /= w;
o_.z /= w;
}
return o_;
}
public static vector3d Create_vector3d(float _x = 0, float _y = 0, float _z = 0)
{
vector3d v_ = new vector3d();
v_.x = _x;
v_.y = _y;
v_.z = _z;
return v_;
}
public static triangle Create_triangle(params vector3d[] _p)
{
triangle t_ = new triangle();
t_.p = _p;
return t_;
}
public static mesh Create_mesh(params triangle[] _t)
{
mesh m_ = new mesh();
m_.tris = _t.ToList();
return m_;
}
public static matrix4x4 Create_matrix4x4(params (int x, int y, float value)[] inputs)
{
matrix4x4 m_ = new matrix4x4();
m_.m = new float[4, 4];
foreach (var item in inputs)
{
m_.m[item.x, item.y] = item.value;
}
return m_;
}
public struct vector3d
{
public float x, y, z;
}
public struct triangle
{
public vector3d[] p;
}
public struct mesh
{
public List<triangle> tris;
}
public struct matrix4x4
{
public float[,] m;
};
}
}
}
I tried storing the cube with the calculated parameters, so I could draw it at once.
This was my only idea..
Related
error CS1031: Type expected and error CS1001: Identifier expected
I'm new here and can't understand many things.I'm writing my fist c# code for a Unity game. I saw a tutorial on YouTube of this code and tried as hard as I could to write it correctly.I checked it many times but can't understand how to solve this problem. What's wrong? /tmp/aTDELDegvF.cs(73,40): error CS1031: Type expected /tmp/aTDELDegvF.cs(73,40): error CS1001: Identifier expected using UnityEngine; using System; using System.Collections; using System.Collections.Generic; public class GameController : MonoBehaviour { private CubePos nowCube = new CubePos(0, 1, 0); public float cubeChangePlacespeed = 0.5f; public Transform cubeToPlace; private List<Vector3> allCubesPositions = new List<Vector3>{ new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(1, 0, 1), new Vector3(-1, 0, -1), new Vector3(-1, 0, 1), new Vector3(1, 0, -1), }; private void Start(){ StartCoroutine(ShowCubePlace()); } IEnumerator ShowCubePlace(){ while(true){ SpawnPositions(); yield return new WaitForSeconds(cubeChangePlacespeed); } } private void SpawnPositions(){ List<Vector3> positions = new List<Vector3>(); if(IsPositionEmpty(new Vector3(nowCube.x + 1, nowCube.y, nowCube.z))) positions.Add(new Vector3(nowCube.x + 1, nowCube.y, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x - 1, nowCube.y, nowCube.z))) positions.Add(new Vector3(nowCube.x - 1, nowCube.y, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y + 1, nowCube.z))) positions.Add(new Vector3(nowCube.x, nowCube.y + 1, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y - 1, nowCube.z))) positions.Add(new Vector3(nowCube.x, nowCube.y - 1, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y, nowCube.z - 1))) positions.Add(new Vector3(nowCube.x, nowCube.y, nowCube.z - 1)); cubeToPlace.position =positions [UnityEngine.Random.Range(0, positions.Count)]; } private bool IsPositionEmpty(Vector3 targetPos){ if(targetPos.y = 0) return false; foreach(Vector3 pos in allCubesPositions){ if(pos.x == targetPos.x && pos.y == targetPos.y && pos.z == targetPos.z) return false; } return true; } } struct CubePos{ public int x, y, z; public CubePos(int x, int y, int z,){ this.x = x; this.y = y; this.z = z; } public Vector3 getVector(){ return new Vector3(x, y, z); } public void setVector(Vector3 pos){ x = Convert.ToInt32(pos.x); y = Convert.ToInt32(pos.y); z = Convert.ToInt32(pos.z); } }
Saving a 2D array as JSON
I Have problem to save my simulation into JSON File. the basics I make a moving ship. in the world space there will be a probe button that will provide information about the ship. I want to save that information into JSON. Anyone know how to do that. I am new in Unity. In button () I want to save the ship information (eg. position, depthsea, windspeed, temperature,flow public class test : MonoBehaviour { // Start is called before the first frame update public GameObject Ship; public GameObject hole; public GameObject turtle; public GameObject panelhole; public GameObject panelturtle; public RectTransform shipvalue; //public RectTransform flowvalue; //public RectTransform windspeedvalue; //public RectTransform temperaturevalue; //public RectTransform depthvalue; public Vector3 offset; public RectTransform Basicobject; //parent //public static bool captureAllKeyboardInput = false; private bool paneloff = false; public float duration = 1; public int[,] grid = new int[10, 16]; public float[,] depth = new float[4, 3] {{1.6f, 2.3f, 3.5f }, {4, 5, 6.5f}, {7, 8, 6.5f}, {7, 8, 6.5f}}; public float[,] temperaturedata = new float[10, 16] {{0, 0, 0, 0, 0, 0, 0, 22.5f, 22.7f, 23, 23.9f, 24, 26.3f, 26.4f, 26.4f, 26.3f}, {0, 0, 0, 0, 0, 0, 22.8f, 23.2f, 23.8f, 24.4f, 25, 24.3f, 26.5f, 26.5f, 26.5f, 26.6f}, {0, 0, 0, 0, 0, 22.5f, 23.1f, 24.8f, 25.3f, 25.7f, 0, 0, 26.7f, 26.3f, 26.2f, 26.6f}, {0, 0, 0, 0, 23.2f, 23.8f, 25.1f, 25.4f, 25.9f, 0, 0, 26.8f, 26.9f, 26.5f, 26.3f, 26.3f}, {0, 0, 24.5f, 23.3f, 23.9f, 24.5f, 25.7f, 25.6f, 26.8f, 0, 0, 26.9f, 27.1f, 26.6f, 26.4f, 26.4f}, {0, 24.1f, 23.9f, 24.9f, 25.4f, 25.5f, 25.9f, 27.4f, 27.2f, 0, 0, 27, 27.2f, 26.8f, 26.4f, 26 }, {27.4f, 27.7f, 27.3f, 26.2f, 26.2f, 25.9f, 27.5f, 27.7f, 27.3f, 0, 26.8f, 27.2f, 27.2f, 26.9f, 26.4f, 26.2f}, {28.5f, 29, 27.5f, 27.3f, 27.3f, 27.5f, 27.7f, 27.7f, 27.5f, 27.2f, 27.2f, 27.4f, 27.4f, 26.9f, 26.3f, 26.7f}, {28.5f, 27.6f, 27.1f, 27, 26.5f, 27.6f, 27.6f, 27.6f, 27.7f, 27.4f, 27.8f, 27.7f, 27.7f, 27, 27, 26.6f}, {28.5f, 27.6f, 25, 27.3f, 26.8f, 27.8f, 27.3f, 27.5f, 28.1f, 27.9f, 28, 27.6f, 27.7f, 26.9f, 27.1f, 26.8f}}; public float[,] flowdata = new float[10, 16] {{0, 0, 0, 0, 0, 0, 0, 0.4f, 0.4f, 0.6f, 0.8f, 0.6f, 0.7f, 0.4f, 0.4f, 0.4f}, {0, 0, 0, 0, 0, 0, 0.3f, 0.5f, 0.5f, 0.8f, 0.8f, 0.8f, 0.6f, 0.6f, 0.5f, 0.5f}, {0, 0, 0, 0, 0, 0.4f, 0.7f, 0.7f, 0.7f, 0.7f, 0, 0, 0.9f, 0.6f, 0.4f, 0.4f}, {0, 0, 0, 0, 0.5f, 0.5f, 0.6f, 0.7f, 0.6f, 0, 0, 0.8f, 0.8f, 0.4f, 0.3f, 0.3f}, {0, 0, 000, 0.7f, 0.6f, 0.5f, 0.7f, 1, 0.8f, 0, 0, 0.9f, 0.5f, 0.3f, 0.1f, 0.3f}, {0, 0.5f, 0.7f, 0.6f, 0.8f, 0.8f, 1.3f, 0.9f, 0.5f, 0, 0, 0.8f, 0.3f, 0.1f, 0.2f, 0.2f}, {0.6f, 0.6f, 0.6f, 0.7f, 1.1f, 0.9f, 0.8f, 0.4f, 0.3f, 0, 0.9f, 0.6f, 0.2f, 0.2f, 0.2f, 0.2f}, {0.4f, 0.4f, 0.5f, 0.5f, 0.3f, 0.4f, 0.3f, 0.2f, 0.4f, 0.2f, 0.8f, 0.3f, 0.2f, 0.2f, 0.2f, 0.1f}, {000, 0.3f, 0.5f, 0.2f, 0.2f, 0.2f, 0.2f, 0.1f, 0.2f, 0.6f, 0.6f, 0.3f, 0.3f, 0.2f, 0.2f, 0.2f}, {000, 000, 0.1f, 0.4f, 0.3f, 0.3f, 0.2f, 0.2f, 0.1f, 0.2f, 0.3f, 0.1f, 0.2f, 0.2f, 0.2f, 0.2f}}; public float[,] windspeeddata = new float[10, 12] {{0,0,0,0,0,0,0,4,4,4,3,3}, {0,0,0,0,0,0,4,5,4,3,3,3}, {0,0,0,0,0,5,5,5,5,3,0,0}, {0,0,0,0,4,4,4,4,4,0,0,3}, {0,0,3,0,4,4,4,4,4,0,0,3}, {0,4,4,4,4,4,4,4,3,0,0,3}, {4,4,4,4,4,4,4,3,3,0,3,4}, {5,4,4,4,4,4,3,3,3,3,4,4}, {4,4,4,4,4,4,3,3,3,3,4,4}, {5,4,4,4,4,4,4,4,4,3,3,3}}; int row, column, num1, num2; int p1; int p2; int[] grid2 = new int[5]; public Text shiposition = null; public Text depthtext = null; public Text windspeedtext = null; public Text temperaturetext = null; public Text flowtext = null; //direction = Ship.transform.rotation.z; float LastMove; float timeIn = 0.5f; public Vector3 direction; float zvalue; [Serializable] public class ShipData { public int grid; public float depth; public float windspeed; public float temperature; } [SerializeField] private ShipData JSON_ShipData = new ShipData(); public void SaveintoJson() { string data = JsonUtility.ToJson(JSON_ShipData); System.IO.File.WriteAllText(Application.persistentDataPath + "/DataCenter.json", data); Debug.Log("Saving as JSON" + JSON_ShipData); Debug.Log(Application.persistentDataPath); } void Start() { p1 = 9; p2 = 0; grid[p1, p2] = 1; panelhole.SetActive(false); panelturtle.SetActive(false); Debug.Log(grid[p1, p2]); Debug.Log(shiposition.transform.position); } // Update is called once per frame void Update() { //Debug.Log(Ship.transform.localEulerAngles.z); zvalue = Ship.transform.localEulerAngles.z; if (Input.GetKeyDown(KeyCode.RightArrow)) { StartCoroutine(Forward()); } if (Input.GetKeyDown(KeyCode.LeftArrow)) { StartCoroutine(Backward()); } if (Input.GetKeyDown(KeyCode.DownArrow)) { StartCoroutine(Rotate(Vector3.forward, -90, 1.0f)); Debug.Log(transform.rotation.eulerAngles.z); } if (Input.GetKeyDown(KeyCode.UpArrow)) { StartCoroutine(Rotate(Vector3.forward, 90, 1.0f)); Debug.Log(transform.rotation.eulerAngles.z); } if (Time.time - LastMove > timeIn) { LastMove = Time.time; } if (Input.GetKeyDown(KeyCode.W)) { StartCoroutine(Rotate(Vector3.forward, 90, 1.0f)); // position(grid); // depthsea(depth); } if (Input.GetKeyDown(KeyCode.A)) { if (p2 >= 0) { StartCoroutine(Backward()); grid[p1, p2] = 0; grid[p1, --p2] = 1; //position(grid); //depthsea(depth); } else { Debug.Log("You can't move left!!"); } } if (Input.GetKeyDown(KeyCode.D)) { // z = 0 if (p2 <= 12 && zvalue == 0) { StartCoroutine(Forward()); grid[p1, p2] = 0; grid[p1, ++p2] = 1; //position(grid); //depthsea(depth); Debug.Log(zvalue); } // z = 270 else if (p2 <= 12 && zvalue == 270) { StartCoroutine(Forward()); grid[p1, p2] = 0; grid[++p1, p2] = 1; // position(grid); //depthsea(depth); Debug.Log(zvalue); } //// z = 180 else if (p2 <= 12 && zvalue == 180) { StartCoroutine(Forward()); grid[p1, p2] = 0; grid[p1, --p2] = 1; // position(grid); //depthsea(depth); Debug.Log(zvalue); } //// z = 90 else if (p2 <= 12 && zvalue == 90) { StartCoroutine(Forward()); grid[p1, p2] = 0; grid[--p1, p2] = 1; // position(grid); //depthsea(depth); Debug.Log(zvalue); } else { Debug.Log("You can't move right any further!!"); Debug.Log(Ship.transform.localEulerAngles.z); } } if (Input.GetKeyDown(KeyCode.S)) { StartCoroutine(Rotate(Vector3.forward, -90, 1.0f)); //position(grid); //depthsea(depth); } //WebGLInput.captureAllKeyboardInput = false; } private void position(int[,] grid) { for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { if (grid[i, j] == 1) { // Debug.Log("x: " + i + " y: " + j + " Grid: " + grid[i, j]); shiposition.text = "X : " + i + " " + "Y : " + j; shiposition.text.ToString(); PlayerPrefs.SetString("position", shiposition.text); PlayerPrefs.Save(); Debug.Log(shiposition.text); } } } } public void windspeed(float[,] windspeeddata) { for (int x = 0; x < windspeeddata.GetLength(0); x++) { for (int y = 0; y < windspeeddata.GetLength(1); y++) { if (grid[x, y] == 1) { windspeedtext.text = "Windspeed Level :" + windspeeddata[x, y]; } } } } public void temperature(float[,] temperaturedata) { for (int x = 0; x < temperaturedata.GetLength(0); x++) { for (int y = 0; y < temperaturedata.GetLength(1); y++) { if (grid[x, y] == 1) { //Debug.Log(temperaturedata[x, y]); temperaturetext.text = "Temperature :" + temperaturedata[x, y] + "C"; } } } } public void flow(float[,] flowdata) { for (int x = 0; x < flowdata.GetLength(0); x++) { for (int y = 0; y < flowdata.GetLength(1); y++) { if (grid[x, y] == 1) { flowtext.text = "Flow :" + flowdata[x, y]; } } } } public void depthsea(float[,] depth) { for (int x = 0; x < depth.GetLength(0); x++) { for (int y = 0; y < depth.GetLength(1); y++) { if (grid[x, y] == 1) { depthtext.text = "Depth :" + depth[x, y]; Debug.Log(depth[x, y]); } } } } public void moveobject() { shipvalue.transform.position = Ship.transform.position; //shipvalue.transform.position.y + 0.5f; //flowvalue.transform.position = Ship.transform.position; //windspeedvalue.transform.position = Ship.transform.position; //temperaturevalue.transform.position = Ship.transform.position; //depthvalue.transform.position = Ship.transform.position; } public void button() { position(grid); depthsea(depth); windspeed(windspeeddata); temperature(temperaturedata); flow(flowdata); moveobject(); //value.transform.position = Ship.transform.position; //string newposition = JsonUtility.ToJson(shiposition.text); //System.IO.File.WriteAllText(Application.persistentDataPath + "PositionData.json", newposition); //Debug.Log(shiposition.text); }
The JSON export itself should work that way However, never use + "/" for system file paths. Rather use Path.Combine which inserts the correct path separator automatically System.IO.File.WriteAllText(Path.Combine(Application.persistentDataPath, "DataCenter.json", data); Main Problem You are never assigning any values into the JSON_ShipData so you will always export a JSON with default values! So first what you want is to store a Vector2Int for the position [Serializable] public class ShipData { public Vector2Int position; public float depth; public float windspeed; public float temperature; } Then you probably would want to update the content at certain places like e.g. private bool TryGetPosition(int[,] grid, out Vector2Int position) { position = default; for (int x = 0; x < grid.GetLength(0); i++) { for (int y = 0; y < grid.GetLength(1); j++) { if (grid[x, y] == 1) { // store into the returned out value position = new Vector2Int(x, y); shiposition.text = $"X : {x} Y : {y}"; shiposition.text.ToString(); PlayerPrefs.SetInt("positionX", position.x); PlayerPrefs.SetInt("positionY", position.y); PlayerPrefs.Save(); Debug.Log(shiposition.text); return true; } } } return false; } Note that this is also more efficient since it doesn't iterate through the rest of your grid if it already has found the position Repeat the same for your other methods and then use them like e.g. public void button() { // Check if a position is found and if yes update the json data if(TryGetPosition(grid, out var position) { JSON_ShipData.position = position; } // Repeat the same for your other values SaveintoJson(); } General notes: Before doing stuff like grid[p1, --p2] = 1; You should always check if your are maybe getting out of bounds e.g. like private bool TryGoToPosition(int[,] grid, Vector2Int from, Vector2Int to) { if(to.x >= 0 && to.x < grid.GetLength(0) - 1 && to.y >= 0 && to.y < grid.GetLength(1) - 1) { grid[from.x, from.y] = 0; grid[to.x, to.x] = 1; } else { Debug.LogWarning("Reached grid border! -> Ignored"); } } Then I would simply work with a Vector2Int in general instead of setting some value in a grid to 0 or 1 like Vector2Int gridDimensions = new Vector2Int(10, 16); public ShipData currentShipData; public ShipData JSON_ShipData; private bool CanGoToPosition(Vector2Int to) { return to.x >= 0 && to.x < gridDimensions.x - 1 && to.y >= 0 && to.y < gridDimensions.y - 1; } void Start() { currentShipData.position = new Vector2Int(9, 0); panelhole.SetActive(false); panelturtle.SetActive(false); Debug.Log(JSON_ShipData.position); Debug.Log(shiposition.transform.position); } void Update() { ...... if (Input.GetKeyDown(KeyCode.A)) { if (CanGoToPosition(JSON_ShipData.position + Vector2Int.down)) { currentShipData.position += Vector2Int.down; } else { Debug.Log("You can't move left!!"); } } ... // Then after you handled user input for movement update the other data currentShipData.windspeed = windspeedData[JSON_ShipData.position.x, JSON_ShipData.position.y]; currentShipData.flow = flowData[JSON_ShipData.position.x, JSON_ShipData.position.y]; ... } Then for the button press you simply only copy over the current values public void button() { JSON_ShipData.position = currentShipData.position; ... SaveintoJson(); }
Marching Cubes generating holes in mesh
I'm working on a Marching Cubes implementation in Unity. My code is based on Paul Bourke's code actually with a lot of modifications, but anyway i'm checking if a block at a position is null if it is than a debug texture will be placed on it. This is my MC script public class MarchingCubes { private World world; private Chunk chunk; private List<Vector3> vertices = new List<Vector3> (); private List<Vector3> normals = new List<Vector3> (); private Vector3[] ns; private List<int> triangles = new List<int> (); private List<Vector2> uvs = new List<Vector2> (); private Vector3[] positions = new Vector3[8]; private float[] corners = new float[8]; private Vector3i size = new Vector3i (16, 128, 16); Vector3[] vertlist = new Vector3[12]; private float isolevel = 1f; private float Corner (Vector3i pos) { int x = pos.x; int y = pos.y; int z = pos.z; if (x < size.x && z < size.z) { return chunk.GetValue (x, y, z); } else { int ix = chunk.X, iz = chunk.Z; int rx = chunk.region.x, rz = chunk.region.z; if (x >= size.x) { ix++; x = 0; } if (z >= size.z) { iz++; z = 0; } return chunk.region.GetChunk (ix, iz).GetValue (x, y, z); } } Block block; public Mesh MarchChunk (World world, Chunk chunk, Mesh mesh) { this.world = world; this.chunk = chunk; vertices.Clear (); triangles.Clear (); uvs.Clear (); for (int x = 0; x < size.x; x++) { for (int y = 1; y < size.y - 2; y++) { for (int z = 0; z < size.z; z++) { block = chunk.GetBlock (x, y, z); int cubeIndex = 0; for (int i = 0; i < corners.Length; i++) { corners [i] = Corner (new Vector3i (x, y, z) + offset [i]); positions [i] = (new Vector3i (x, y, z) + offset [i]).ToVector3 (); if (corners [i] < isolevel) cubeIndex |= (1 << i); } if (eTable [cubeIndex] == 0) continue; for (int i = 0; i < vertlist.Length; i++) { if ((eTable [cubeIndex] & 1 << i) == 1 << i) vertlist [i] = LinearInt (positions [eCons [i, 0]], positions [eCons [i, 1]], corners [eCons [i, 0]], corners [eCons [i, 1]]); } for (int i = 0; triTable [cubeIndex, i] != -1; i += 3) { int index = vertices.Count; vertices.Add (vertlist [triTable [cubeIndex, i]]); vertices.Add (vertlist [triTable [cubeIndex, i + 1]]); vertices.Add (vertlist [triTable [cubeIndex, i + 2]]); float tec = (0.125f); Vector2 uvBase = block != null ? block.UV : new Vector2 (); uvs.Add (uvBase); uvs.Add (uvBase + new Vector2 (0, tec)); uvs.Add (uvBase + new Vector2 (tec, tec)); triangles.Add (index + 0); triangles.Add (index + 1); triangles.Add (index + 2); } } } } if (mesh == null) mesh = new Mesh (); mesh.Clear (); mesh.vertices = vertices.ToArray (); mesh.triangles = triangles.ToArray (); mesh.uv = uvs.ToArray (); mesh.RecalculateNormals (); return mesh; } bool IsBitSet (int b, int pos) { return ((b & pos) == pos); } Vector3 LinearInt (Vector3 p1, Vector3 p2, float v1, float v2) { Vector3 p; p.x = p1.x + (isolevel - v1) * (p2.x - p1.x) / (v2 - v1); p.y = p1.y + (isolevel - v1) * (p2.y - p1.y) / (v2 - v1); p.z = p1.z + (isolevel - v1) * (p2.z - p1.z) / (v2 - v1); return p; } private static int[,] eCons = new int[12, 2] { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }; private static Vector3i[] offset = new Vector3i[8] { new Vector3i (0, 0, 1), new Vector3i (1, 0, 1), new Vector3i (1, 0, 0), new Vector3i (0, 0, 0), new Vector3i (0, 1, 1), new Vector3i (1, 1, 1), new Vector3i (1, 1, 0), new Vector3i (0, 1, 0) }; } I didn't put the tables in the sample, because they are the same as the ones in Bourke's code. EDIT: What I figured out yet is that the cell's value at the blue triangles are 0 so they don't have to be triangulated, but the cell's value under them is 1 and because of this a top triangle is created to complete the mesh.
How to fill enclosed area in the Bitmap object with a color
Give point within the region with a color to fill the region, similar to the "drawing" in the paint bucket function. The. NET Framework, there is no direct equivalent. but i hope use C# to do it. is it possible?
Here's a very naive flood fill algorithm that should get you started void Form1_Paint(object sender, PaintEventArgs e) { using (Bitmap bitmap = new Bitmap(500, 500)) { using (Graphics g = Graphics.FromImage(bitmap)) { g.Clear(Color.White); List<Point> points = new List<Point>(); for (double i = 0; i < 10; i++) { double dist = (i % 2 == 0) ? 100 : 50; double x = 200 + Math.Cos(i / 10d * Math.PI * 2d) * dist; double y = 200 + Math.Sin(i / 10d * Math.PI * 2d) * dist; points.Add(new Point((int)x, (int)y)); } g.DrawPolygon(Pens.Black, points.ToArray()); } FloodFill(bitmap, 200, 200, Color.Red); e.Graphics.DrawImage(bitmap, 0, 0); } } void FloodFill(Bitmap bitmap, int x, int y, Color color) { BitmapData data = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int[] bits = new int[data.Stride / 4 * data.Height]; Marshal.Copy(data.Scan0, bits, 0, bits.Length); LinkedList<Point> check = new LinkedList<Point>(); int floodTo = color.ToArgb(); int floodFrom = bits[x + y * data.Stride / 4]; bits[x + y * data.Stride / 4] = floodTo; if (floodFrom != floodTo) { check.AddLast(new Point(x, y)); while (check.Count > 0) { Point cur = check.First.Value; check.RemoveFirst(); foreach (Point off in new Point[] { new Point(0, -1), new Point(0, 1), new Point(-1, 0), new Point(1, 0)}) { Point next = new Point(cur.X + off.X, cur.Y + off.Y); if (next.X >= 0 && next.Y >= 0 && next.X < data.Width && next.Y < data.Height) { if (bits[next.X + next.Y * data.Stride / 4] == floodFrom) { check.AddLast(next); bits[next.X + next.Y * data.Stride / 4] = floodTo; } } } } } Marshal.Copy(bits, 0, data.Scan0, bits.Length); bitmap.UnlockBits(data); }
Calculate volume of 3D mesh
i get tired to calculate the volume of 3D object (Cube, Cylinder ...) can any one help with this problem ? the question is , how to calculate the volume of object from his coordinates based on triangles. my class don't do well the job , any one help me to emproove the class ? thanks public class Algorithm { private Mesh _mesh { get; set; } public Algorithm(Mesh mesh) { _mesh = mesh; } private double SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 p3) { var v321 = p3.X * p2.Y * p1.Z; var v231 = p2.X * p3.Y * p1.Z; var v312 = p3.X * p1.Y * p2.Z; var v132 = p1.X * p3.Y * p2.Z; var v213 = p2.X * p1.Y * p3.Z; var v123 = p1.X * p2.Y * p3.Z; return (1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123); } public double VolumeOfMesh() { double volume = 0.0; Vector3[] vertices = _mesh.Vertices; int[] triangles = _mesh.Triangles; for (int i = 0; i < _mesh.Triangles.Length; i += 3) { Vector3 p1 = vertices[triangles[i + 0]]; Vector3 p2 = vertices[triangles[i + 1]]; Vector3 p3 = vertices[triangles[i + 2]]; volume += SignedVolumeOfTriangle(p1, p2, p3); } return Math.Abs(volume); } } public class Mesh { public Mesh(Vector3[] _vertices,int[] _triangles) { Vertices = _vertices; Triangles = _triangles; } public Vector3[] Vertices { get; set; } public int[] Triangles { get; set; } } public class Vector3 { public Vector3() { } public Vector3(double x,double y,double z) { X = x; Y = y; Z = z; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } } private void button1_Click(object sender, EventArgs e) { Vector3[] vers = new Vector3[8] { new Vector3 {X = 5,Y = 5,Z =5}, new Vector3 {X = 15,Y = 5,Z =5}, new Vector3 {X = 15,Y = 15,Z =5}, new Vector3 {X = 5,Y = 15,Z =5}, new Vector3 {X = 5,Y = 5,Z =15}, new Vector3 {X = 15,Y = 5,Z =15}, new Vector3 {X = 15,Y = 15,Z =15}, new Vector3 {X = 5,Y = 15,Z =15}, }; int[] trs = new int[36] { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 1, 6, 2, 1, 5, 6, 0, 4, 7, 0, 7, 3, 0, 1, 5, 0, 5, 4, 3, 2, 6,3, 6, 7 }; Mesh mesh = new Mesh(vers, trs); Algorithm algo = new Algorithm(mesh); var vol = algo.VolumeOfMesh(); MessageBox.Show(vol.ToString()); } The result of my test is vol = 666,666 but it should be 1000.
The line double v132 = (p3.X - basePoint.X) * (p3.Y - basePoint.Y) * (p2.Z - basePoint.Z); Is not correct according to How to calculate the volume of a 3D mesh object the surface of which is made up triangles it should be (notice the p1.X instead of p3.X): var v132 = p1.X*p3.Y*p2.Z; EDIT Although you marked this answer as correct I tested the code and found more errors. The triangles are not all facing outward (or inward) by adjusting the triangle indices like this: 0, 1, 2, 0, 2, 3, 4, 6, 5, 4, 7, 6,// adjusted 1, 6, 2, 1, 5, 6, 0, 7, 4,// adjusted 0, 3, 7,// adjusted 0, 5, 1,// adjusted 0, 4, 5,// adjusted 3, 2, 6, 3, 6, 7 all normals face outward. the calculation then returns -1000 the minus depending on the base offset.