What is the way to set and get position of imported STL file. I'm looking for a solution to set position x,y,z to imported STL file like is possible for example to Joint.
Normally things are moved in eyeshot by a transformation matrix. This matrix consists of a rotation matrix 3 x 3, a location 1 x 3, and skew/stretch 4 x 1. All together this makes a 4 x 4 transformation matrix.
an imported stl actually contains lots of locations. But all you need to do is grab one of these. below I have just grabbed the min point of the bounding box.
Then to get to a place create an identity transformation matrix to ensure the rotation and skew are Zero. Now insert your location into the location part of the matrix. The transformBy function will now move every point of the stl to a new location.
to move between points you need the vector difference between the points.
Mesh myMesh = Mesh.CreateBox(10, 10, 10);
//Mesh myMesh = new Mesh();
Point3D getLocation = myMesh.BoxMin;
Point3D setLocation = new Point3D(20, -10, 0);
Point3D moveVector = setLocation - getLocation;
Transformation goPlaces = new Transformation(1);
goPlaces[0, 3] = moveVector.X;
goPlaces[1, 3] = moveVector.Y;
goPlaces[2, 3] = moveVector.Z;
//Transformation goPlaces = new Transformation(
// new double[,]
// {
// { 1, 0, 0, 20 },
// { 0, 1, 0,-10 },
// { 0, 0, 1, 0 },
// { 0, 0, 0, 1 }
// }
//);
Transformation goBack = (Transformation)goPlaces.Clone();
goBack.Invert();
myMesh.TransformBy(goPlaces);
myMesh.TransformBy(goBack);
Cheers!
Related
I'm trying to learn how to use OpenGL in a 2D application by using OpenTK and have read that using the inbuilt calls glMatrixMode are not modern. I want to use top left origin and pixel co-ordinates in my shader inputs and assumed I could define a matrix to do these translations.
I am trying to do this using my own matrix using the OpenTK matrix clases. However I think I have made a mistake in setting up the projection matrix and want to verify what I should be doing:-
TranslationMatrix = Matrix4.Identity * Matrix4.CreateScale(1, -1, 1);
TranslationMatrix = TranslationMatrix * Matrix4.CreateOrthographicOffCenter(0, bounds.Width, 0, bounds.Height, -1, 1);
var TranslatedPoint = TranslationMatrix * new Vector4(new Vector3(1024, 768, 0), 1); // bounds = {0, 0, 1024, 768 }
This results in x.Xyz == { 2, -2, 0 }. I thought that the x and y co-ordinates used in gl_position in the vertex shader should range from -1 to 1.
I guess I've got a major misunderstanding somewhere, what should I be looking at?
OpenTK stores the matrices in transposed form. This means you have to write everything in reversed order.
var TranslationMatrix = Matrix4.CreateOrthographicOffCenter(0, bounds.Width, 0, bounds.Height, -1, 1);
TranslationMatrix = TranslationMatrix * Matrix4.CreateScale(1, -1, 1);
var TranslatedPoint = new Vector4(1024, 768, 0, 1) * TranslationMatrix;
The result should now be [1, -1, 0, 1].
I need help from any C# and or OpenCV experts in making my circle detection script more accurate.
In OpenCV circle detection is accomplished by something called HoughCircles algorithm or framework.
http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html
I am using a C# wrapper of OpenCV (for Unity)OpenCVforUnity HughCircles
which in turn is directly based on the official java wrapper of OpenCV.
My circle detection code is as follows (without the OpenCv dependencies of course)
I've also attached 2 images so you can see the results.
What changes are needed to improve the results? I've also included the original 2 images for reference.
using UnityEngine;
using System.Collections;
using System;
using OpenCVForUnity;
public class HoughCircleSample : MonoBehaviour{
Point pt;
// Use this for initialization
void Start ()
{
Texture2D imgTexture = Resources.Load ("balls2_bw") as Texture2D;
Mat imgMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC3);
Utils.texture2DToMat (imgTexture, imgMat);
//Debug.Log ("imgMat dst ToString " + imgMat.ToString ());
Mat grayMat = new Mat ();
Imgproc.cvtColor (imgMat, grayMat, Imgproc.COLOR_RGB2GRAY);
Imgproc.Canny (grayMat, grayMat, 50, 200);
Mat circles = new Mat();
int minRadius = 0;
int maxRadius = 0;
// Apply the Hough Transform to find the circles
Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 3, grayMat.rows() / 8, 200, 100, minRadius, maxRadius);
Debug.Log ("circles toString " + circles.ToString ());
Debug.Log ("circles dump" + circles.dump ());
if (circles.cols() > 0)
for (int x = 0; x < Math.Min(circles.cols(), 10); x++)
{
double[] vCircle = circles.get(0, x);
if (vCircle == null)
break;
pt = new Point(Math.Round(vCircle[0]), Math.Round(vCircle[1]));
int radius = (int)Math.Round(vCircle[2]);
// draw the found circle
Core.circle(imgMat, pt, radius, new Scalar(255, 0, 0), 1);
}
Texture2D texture = new Texture2D (imgMat.cols (), imgMat.rows (), TextureFormat.RGBA32, false);
Utils.matToTexture2D (imgMat, texture);
gameObject.GetComponent<Renderer> ().material.mainTexture = texture;
}
}
This code is in C++, but you can easily convert to C#.
I needed to change the param2 of HoughCircle to 200, resulting in:
HoughCircles(grayMat, circles, CV_HOUGH_GRADIENT, 3, grayMat.rows / 8, 200, 200, 0, 0);
which is
the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first.
You also should't feed HoughCircles with a "Canny-ed" image, since will already take care of this. Use the grayMat without Canny edge detection step applied.
Results are shown below. The second one is more tricky, because of the light conditions.
Here is the whole code. Again, it's C++, but may be useful as a reference.
#include <opencv2/opencv.hpp>
using namespace cv;
int main(){
Mat3b src = imread("path_to_image");
Mat1b src_gray;
cvtColor(src, src_gray, CV_BGR2GRAY);
vector<Vec3f> circles;
HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 3, src_gray.rows / 8, 200, 200, 0, 0);
/// Draw the circles detected
for (size_t i = 0; i < circles.size(); i++)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// circle center
circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
// circle outline
circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
}
imshow("src", src);
waitKey();
return 0;
}
In the fourth parameter you have set a 3, but most of your images have a ratio close to 1, this could be a probable improvement, also you have to try another set of values in the parameters 6 and 7, because this values depend on the contours extracted by a canny edge detector, I hope this could help you.
I'm getting much closer now with 2 overlapping circles for each ball object. If I can correct for this it is basically solved.
Imgproc.Canny (grayMat, grayMat, 500, 200);
Mat circles = new Mat();
int minRadius =50;
int maxRadius = 200;
Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 1, grayMat.rows() / 4, 1000, 1, minRadius, maxRadius);![solution3][1]
I have used this code:
private void ilPanel1_Load(object sender, EventArgs e)
{ using (ILScope.Enter())
{
ILArray<float> X = new float[] { 0, 0, 1, 1, 2.5F, -2.6F, 5, 9, 1, 38 };
ILArray<float> Y = new float[] { 1, 0, 1, 0, 1.5F, 0.5F, 5, 9, 1, 39 };
ILArray<float> Z = new float[] { 0, 0, 1, 1, 0.4F, -0.2F, 5, 9, 1, 39 };
X = X.Reshape(2,5);
Y = Y.Reshape(2,5);
Z = Z.Reshape(2,5);
ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
new ILSurface(Z, colormap: Colormaps.Cool) {
Colors = 1.4f ,Children = { new ILColorbar() }
}
});
}
}
This produces:
However I checked this question and tried to adapt deprecated ILnumerics solution (as I did not find other c# code), but still do not get it, every coordinate (Z,X and Y) corresponds to one slice (m x n) in the array. So it is necesarry to reshape data.
this part is the problem:
X = X.Reshape(2,5);
Y = Y.Reshape(2,5);
Z = Z.Reshape(2,5);
If I do not give correct size, program fails, so in example I have 10 elements on each vector, so when resahping I would put 2,5 which multiplied are 10?...
What about case I have 11 elements as if I put 2,5 on reshape I get error?
What to do?
I have tried using X = X.Reshape(11); but It fails... if I use X = X.Reshape(10); it just do not draw anything
surfaces plot meshes. one must provide a mesh in order to give the surface the chance to understand how to connect the points, which points are meant to be neighbors.
the reshape should not be a problem since the original data must represent the points for a mesh/matrix anyway. so the reshape to that matrix will certainly work.
reshape(10) creates a vector of length 10. since vectors do represent a line at most but not an area - nothing is drawn. remember: surfaces draw meshes or matrices.
I have massive Problems figuring out how to set up a dynamic VertexBuffer and IndexBuffer using SharpDX.
I have to generate Triangles where ever the User presses on the Screen.
I think i have to set up a transformation function that converts my screen coordinates to projection coordinates.
But i dont ever come this far...
I want to set up a Buffer with space for 10000 Vertices.
layout = new InputLayout(d3dDevice, vertexShaderByteCode, new[]
{
new SharpDX.Direct3D11.InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new SharpDX.Direct3D11.InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
});
vb = Buffer.Create(d3dDevice, BindFlags.VertexBuffer, stream, 10000, ResourceUsage.Dynamic, CpuAccessFlags.Write);
vertexBufferBinding = new VertexBufferBinding(vb, Utilities.SizeOf<Vector4>() * 2, 0);
That Buffer i want to update every time i have to add new triangles using:
d3dDevice.ImmediateContext.UpdateSubresource(updateVB, vb);
updateVB are the new Triangles to be added.
Rendering works the following way:
// Prepare matrices
var view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
var proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, width / (float)height, 0.1f, 100.0f);
var viewProj = Matrix.Multiply(view, proj);
// Set targets (This is mandatory in the loop)
d3dContext.OutputMerger.SetTargets(render.DepthStencilView, render.RenderTargetView);
// Clear the views
d3dContext.ClearDepthStencilView(render.DepthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);
d3dContext.ClearRenderTargetView(render.RenderTargetView, Colors.Black);
// Calculate WorldViewProj
var worldViewProj = Matrix.Scaling(1f) * viewProj;
worldViewProj.Transpose();
// Setup the pipeline
d3dContext.InputAssembler.SetVertexBuffers(0, vertexBufferBinding);
d3dContext.InputAssembler.InputLayout = layout;
d3dContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
d3dContext.VertexShader.Set(vertexShader);
d3dContext.PixelShader.Set(pixelShader);
d3dContext.Draw(vertexCount, 0);
I am new to DirectX and the DirectX9 tutorials on the web don't help me very good with DirectX11.1.
Thanks
vb = Buffer.Create(d3dDevice, BindFlags.VertexBuffer, stream, 10000, ResourceUsage.Dynamic, CpuAccessFlags.Write);
Is wrong, since you want 10000 vertices, but allocate 10000 bytes, so should be:
10000 * sizeof(Vector4) * 2
According to your input layout.
Also to write into your buffer, you should look at context.MapSubresource instead.
I've ported 1-1 this code from C++/OpenGL to C# SharpGL:
float[] cameraAngle = { 0, 0, 0 };
float[] cameraPosition = { 0, 0, 10 };
float[] modelPosition = { 0, 0, 0 };
float[] modelAngle = { 0, 0, 0 };
float[] matrixView = new float[16];
float[] matrixModel = new float[16];
float[] matrixModelView = new float[16];
// clear buffer
gl.ClearColor(0.1f, 0.1f, 0.1f, 1);
gl.Clear(OpenGL.COLOR_BUFFER_BIT | OpenGL.DEPTH_BUFFER_BIT | OpenGL.STENCIL_BUFFER_BIT);
// initialze ModelView matrix
gl.PushMatrix();
gl.LoadIdentity();
// ModelView matrix is product of viewing matrix and modeling matrix
// ModelView_M = View_M * Model_M
// First, transform the camera (viewing matrix) from world space to eye space
// Notice all values are negated, because we move the whole scene with the
// inverse of camera transform
gl.Rotate(-cameraAngle[0], 1, 0, 0); // pitch
gl.Rotate(-cameraAngle[1], 0, 1, 0); // heading
gl.Rotate(-cameraAngle[2], 0, 0, 1); // roll
gl.Translate(-cameraPosition[0], -cameraPosition[1], -cameraPosition[2]);
// we have set viewing matrix upto this point. (Matrix from world space to eye space)
// save the view matrix only
gl.GetFloat(OpenGL.MODELVIEW_MATRIX, matrixView); // save viewing matrix
//=========================================================================
// always Draw the grid at the origin (before any modeling transform)
//DrawGrid(10, 1);
// In order to get the modeling matrix only, reset OpenGL.MODELVIEW matrix
gl.LoadIdentity();
// transform the object
// From now, all transform will be for modeling matrix only. (transform from object space to world space)
gl.Translate(modelPosition[0], modelPosition[1], modelPosition[2]);
gl.Rotate(modelAngle[0], 1, 0, 0);
gl.Rotate(modelAngle[1], 0, 1, 0);
gl.Rotate(modelAngle[2], 0, 0, 1);
// save modeling matrix
gl.GetFloat(OpenGL.MODELVIEW_MATRIX, matrixModel);
//=========================================================================
// re-strore OpenGL.MODELVIEW matrix by multiplying matrixView and matrixModel before drawing the object
// ModelView_M = View_M * Model_M
gl.LoadMatrixf(matrixView); // Mmv = Mv
gl.MultMatrixf(matrixModel); // Mmv *= Mm
// save ModelView matrix
gl.GetFloat(OpenGL.MODELVIEW_MATRIX, matrixModelView);
//=========================================================================
// Draw a teapot after ModelView transform
// v' = Mmv * v
//DrawAxis(4);
//DrawTeapot();
gl.PopMatrix();
It doesn't look like the ModelView matrix gets multiplied, the result is the Identity Matrix!
What could be wrong??
Thanks
wrong glMatrixMode?