How to assume spiral parameters? - algorithm

Could someone help me in understanding what paramaters assume to have such spiral as in this question:Draw equidistant points on a spiral?
I don't understant this parameter: rotation- Overall rotation of the spiral. ('0'=no rotation, '1'=360 degrees, '180/360'=180 degrees) I would be grateful if someone write some sets of parameters (sides,coils,rotation) to get spiral.
It's code in Matlab:
clc
clear all
centerX = 0
centerY = 0
radius = 10
coils = 30
rotation = 360
chord = 2
delta = 1
thetaMax = coils * 2 * pi;
awayStep = radius / thetaMax;
i = 1
for theta = (chord / awayStep):thetaMax;
away = awayStep * theta;
around = theta + rotation;
x(i) = centerX + cos ( around ) * away;
y(i) = centerY + sin ( around ) * away;
i = i + 1
theta = theta + (chord / away);
theta2 = theta + delta
away2 = away + awayStep * delta
delta = 2 * chord / ( away + away2 )
delta = 2 * chord / ( 2*away + awayStep * delta )
2*(away + awayStep * delta ) * delta == 2 * chord
awayStep * delta * 2 + 2*away * delta - 2 * chord == 0
a= awayStep; b = 2*away; c = -2*chord
delta = ( -2 * away + sqrt ( 4 * away * away + 8 * awayStep * chord ) ) / ( 2 * awayStep );
theta = theta + delta;
end
v = [0 x]
w = [0 y]
scatter(v,w)
Thank you in advance

Related

Controlling a virtual character's joints rotation with OpenNI + Kinect

I'm starting a project where I need to control a virtual character. The character is being rendered in multiple 3D engines, such as Three.JS and iOS SceneKit.
I'm getting the Quaternions of every joint of the skeleton with OpenNI, and it looks kind of like this:
The code that saves and pass the quaternion, looks like this:
float confidence = context.getJointOrientationSkeleton(userId, jointName,
joint);
joints[jointIndex]=joint.m00;
joints[jointIndex+1]=joint.m01;
joints[jointIndex+2]=joint.m02;
joints[jointIndex+3]=joint.m10;
joints[jointIndex+4]=joint.m11;
joints[jointIndex+5]=joint.m12;
joints[jointIndex+6]=joint.m20;
joints[jointIndex+7]=joint.m21;
joints[jointIndex+8]=joint.m22;
jointIndex+=9;
This repeats for every joint of the skeleton.
The last row and last column is always [0 0 0 1] [0, 0, 0, 1], so I just append that on the client once I receive it and build a 4x4 matrix.
I want to be able to make the right rotations with this data, but the rotations I'm getting are definitely wrong.
This is how I'm processing the matrix: (pseudo-code)
row1 = [m00 m01 m02 0]
row2 = [m10 m11 m12 0]
row3 = [m20 m21 m22 0]
row4 = [0 0 0 1]
matrix4by4 = matrix4x4(rows:[row1,row2,row3,row4])
And then I got the quaternion with two methods, and both methods were showing bad rotations, I cannot find what's wrong or what I'm missing.
First method
There's an iOS function that gets a 3x3 or 4x4 matrix, and transforms it into quaternion:
boneRotation = simd_quatf.init(matrix4by4).vector //X,Y,Z,W
Second method
I found the following code on the web:
let tr = m00 + m11 + m22
var qw = 0
var qx = 0
var qy = 0
var qz = 0
if (tr > 0) {
var S = sqrt(tr+1.0) * 2 // S=4*qw
qw = 0.25 * S
qx = (m21 - m12) / S
qy = (m02 - m20) / S
qz = (m10 - m01) / S
} else if ((m00 > m11) && (m00 > m22)) {
var S = sqrt(1.0 + m00 - m11 - m22) * 2 // S=4*qx
qw = (m21 - m12) / S
qx = 0.25 * S
qy = (m01 + m10) / S
qz = (m02 + m20) / S
} else if (m11 > m22) {
var S = sqrt(1.0 + m11 - m00 - m22) * 2 // S=4*qy
qw = (m02 - m20) / S
qx = (m01 + m10) / S
qy = 0.25 * S
qz = (m12 + m21) / S
} else {
let S = sqrt(1.0 + m22 - m00 - m11) * 2 // S=4*qz
var = (m10 - m01) / S
qx = (m02 + m20) / S
qy = (m12 + m21) / S
qz = 0.25 * S
}
boneRotation = vector4(qx, qy, qw, qz)
I started testing only with shoulder and elbow rotation to help me visualize what could be wrong or missing, and made a video.
Here's how it's behaving: https://www.youtube.com/watch?v=xUtNiwH_AGk
What could I be missing? For example, the axis of rotation of the shoulder are like this:
X-Axis
Y-Axis
Z-Axis
Thank you in advance :-)
YouTuve Video: https://www.youtube.com/watch?v=xUtNiwH_AGk

Calculate square around a lat/long

I'm trying to calc a square around a single point but I keep getting a rectangle.
This is the point -80.42816162109375, 26.686729520004036.
Here's what it looks like:
What am I doing wrong?
int lat_feet = long_feet = 50;
double lat_meters = lat_feet * .3048;
double long_meters = long_feet * .3048;
var earth = 6378137;
var l1 = lat + (180 / Math.PI) * (lat_meters / earth);
var l2 = llong + (180 / Math.PI) * (long_meters / earth) / Math.Cos(lat);

Three.js - Bend plane with spherical coordinates

I try to bend a plane mesh using spherical coordinates. I token formulas on wikipedia and it almost work !
But some vertices are positionned to the same place.
The mesh plane is placed at 0,0,0, you can watch the result here :
Before : http://hpics.li/78c0871
After : http://hpics.li/19ada1a
And here is my code :
#radius = 4
#oPhi = 0
#oTheta = 0
projection : (vertice) ->
p = Math.sqrt(vertice.x ** 2 + vertice.y ** 2)
c = Math.asin(p/#radius)
phi = Math.asin(Math.cos(c) * Math.sin(#oPhi) + (vertice.y * Math.sin(c) * Math.cos(#oPhi) / p))
theta = #oTheta + Math.atan((vertice.x * Math.sin(c)) / (p * Math.cos(#oPhi) * Math.cos(c) - vertice.y * Math.sin(#oPhi) * Math.sin(c)))
vertice.x = #radius * Math.sin(phi) * Math.cos(theta)
vertice.z = #radius * Math.sin(phi) * Math.sin(theta)
vertice.y = #radius * Math.cos(phi)
Thanks for help !
Sorry for that, but the formulas concern le orthographic projection as you can see here :
http://fr.wikipedia.org/wiki/Projection_orthographique

Tinting a terrain model in a radius around a given point in XNA 4.0

I'm writing a game in Visual Studio 2010, using the XNA 4.0 framework. I have a 3D terrain model generated from a height map. What I'm trying to accomplish is to tint this model in a given radius around a certain point, the end goal being to display to the player the radius in which a unit can move in a given turn. The method I'm using to draw the model at the moment is this:
void DrawModel(Model model, Matrix worldMatrix)
{
Matrix[] boneTransforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(boneTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = boneTransforms[mesh.ParentBone.Index] * worldMatrix;
effect.View = camera.viewMatrix;
effect.Projection = camera.projectionMatrix;
effect.EnableDefaultLighting();
effect.EmissiveColor = Color.Green.ToVector3();
effect.PreferPerPixelLighting = true;
// Set the fog to match the black background color
effect.FogEnabled = true;
effect.FogColor = Color.CornflowerBlue.ToVector3();
effect.FogStart = 1000;
effect.FogEnd = 3200;
}
mesh.Draw();
}
}
Also, in case it's relevant, I followed this tutorial http://create.msdn.com/en-US/education/catalog/sample/collision_3d_heightmap to create my heightmap and terrain.
Thanks in advance for any help!
You can use a shader to achieve that...
you only would need to pass as argument the world position of the center and the radius,
and let the pixel shader receive the pixel world position interpolated from the vertex shader as a texture coord...
then only have to check the distance of the pixel position to the center and tint it with a color if the pixel position is in range...
The technique you are looking for is called decaling.
You have to extract the part of the terrain, where the circle will be drawn, apply an appropriate texture to that part and draw it blending it with the terrain.
For the case of a terrain based on a uniform grid, this will look like the following:
You have the center position of the decal and its radius. Then you can determine min and max row/col in the grid, so that the cells include every drawn region. Create a new vertex buffer from these vertices. Positions can be read from the heightmap. You have to alter the texture coordinates, so the texture will be placed at the right position. Assume, the center position has coordinate (0.5, 0.5), center position + (radius, radius) has coordinate (1, 1) and so on. With that you should be able to find an equation for the texture coordinates for each vertex.
In the above example, the top left red vertex has texture coordinates of about (-0.12, -0.05)
Then you have the subgrid of the terrain. Apply the decal texture to it. Set an appropriate depth bias (you have to try out some values). In most cases, a negative SlopeScaleDepthBias will work. Turn off texture coordinate wrapping in the sampler. Draw the subgrid.
Here's some VB SlimDX Code I wrote for that purpose:
Public Sub Init()
Verts = (Math.Ceiling(2 * Radius / TriAngleWidth) + 2) ^ 2
Tris = (Math.Ceiling(2 * Radius / TriAngleWidth) + 1) ^ 2 * 2
Dim Indices(Tris * 3 - 1) As Integer
Dim curN As Integer
Dim w As Integer
w = (Math.Ceiling(2 * Radius / TriAngleWidth) + 2)
For y As Integer = 0 To w - 2
For x As Integer = 0 To w - 2
Indices(curN) = x + y * w : curN += 1
Indices(curN) = x + (y + 1) * w : curN += 1
Indices(curN) = (x + 1) + (y) * w : curN += 1
Indices(curN) = x + (y + 1) * w : curN += 1
Indices(curN) = (x + 1) + (y + 1) * w : curN += 1
Indices(curN) = (x + 1) + y * w : curN += 1
Next
Next
VB = New Buffer(D3DDevice, New BufferDescription(Verts * VertexPosTexColor.Struct.SizeOfBytes, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, VertexPosTexColor.Struct.SizeOfBytes))
IB = New Buffer(D3DDevice, New DataStream(Indices, False, False), New BufferDescription(4 * Tris * 3, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 4))
End Sub
Public Sub Update()
Dim Vertex(Verts - 1) As VertexPosTexColor.Struct
Dim curN As Integer
Dim rad As Single 'The decal radius
Dim height As Single
Dim p As Vector2
Dim yx, yz As Integer
Dim t As Vector2 'texture coordinates
Dim center As Vector2 'decal center
For y As Integer = Math.Floor((center.Y - rad) / TriAngleWidth) To Math.Floor((center.Y - rad) / TriAngleWidth) + Math.Ceiling(2 * rad / TriAngleWidth) + 1
For x As Integer = Math.Floor((center.X - rad) / TriAngleWidth) To Math.Floor((center.X - rad) / TriAngleWidth) + Math.Ceiling(2 * rad / TriAngleWidth) + 1
p.X = x * TriAngleWidth
p.Y = y * TriAngleWidth
yx = x : yz = y
If yx < 0 Then yx = 0
If yx > HeightMap.GetUpperBound(0) Then yx = HeightMap.GetUpperBound(0)
If yz < 0 Then yz = 0
If yz > HeightMap.GetUpperBound(1) Then yz = HeightMap.GetUpperBound(1)
height = HeightMap(yx, yz)
t.X = (p.X - center.X) / (2 * rad) + 0.5
t.Y = (p.Y - center.Y) / (2 * rad) + 0.5
Vertex(curN) = New VertexPosTexColor.Struct With {.Position = New Vector3(p.X, hoehe, p.Y), .TexCoord = t, .Color = New Color4(1, 1, 1, 1)} : curN += 1
Next
Next
Dim data = D3DContext.MapSubresource(VB, MapMode.WriteDiscard, MapFlags.None)
data.Data.WriteRange(Vertex)
D3DContext.UnmapSubresource(VB, 0)
End Sub
And here's the according C# code.
public void Init()
{
Verts = Math.Pow(Math.Ceiling(2 * Radius / TriAngleWidth) + 2, 2);
Tris = Math.Pow(Math.Ceiling(2 * Radius / TriAngleWidth) + 1, 2) * 2;
int[] Indices = new int[Tris * 3];
int curN;
int w;
w = (Math.Ceiling(2 * Radius / TriAngleWidth) + 2);
for(int y = 0; y <= w - 2; ++y)
{
for(int x = 0; x <= w - 2; ++x)
{
Indices[curN] = x + y * w ; curN += 1;
Indices[curN] = x + (y + 1) * w ; curN += 1;
Indices[curN] = (x + 1) + (y) * w ; curN += 1;
Indices[curN] = x + (y + 1) * w ; curN += 1;
Indices[curN] = (x + 1) + (y + 1) * w ; curN += 1;
Indices[curN] = (x + 1) + y * w ; curN += 1;
}
}
VB = new Buffer(D3DDevice, new BufferDescription(Verts * VertexPosTexColor.Struct.SizeOfBytes, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, VertexPosTexColor.Struct.SizeOfBytes));
IB = new Buffer(D3DDevice, new DataStream(Indices, False, False), new BufferDescription(4 * Tris * 3, ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 4));
}
public void Update()
{
VertexPosTexColor.Struct[] Vertex = new VertexPosTexColor.Struct[Verts] ;
int curN;
float rad; //The decal radius
float height;
Vector2 p;
int yx, yz;
Vector2 t; //texture coordinates
Vector2 center; //decal center
for(int y = Math.Floor((center.Y - rad) / TriAngleWidth); y <= Math.Floor((center.Y - rad) / TriAngleWidth) + Math.Ceiling(2 * rad / TriAngleWidth) + 1; ++y)
for(int x = Math.Floor((center.X - rad) / TriAngleWidth); x <= Math.Floor((center.X - rad) / TriAngleWidth) + Math.Ceiling(2 * rad / TriAngleWidth) + 1; ++x)
{
p.X = x * TriAngleWidth;
p.Y = y * TriAngleWidth;
yx = x ; yz = y;
if( yx < 0)
yx = 0;
if (yx > HeightMap.GetUpperBound(0))
yx = HeightMap.GetUpperBound(0);
if (yz < 0)
yz = 0;
if (yz > HeightMap.GetUpperBound(1))
yz = HeightMap.GetUpperBound(1);
height = HeightMap[yx, yz];
t.X = (p.X - center.X) / (2 * rad) + 0.5;
t.Y = (p.Y - center.Y) / (2 * rad) + 0.5;
Vertex[curN] = new VertexPosTexColor.Struct() {Position = new Vector3(p.X, hoehe, p.Y), TexCoord = t, Color = New Color4(1, 1, 1, 1)}; curN += 1;
}
}
var data = D3DContext.MapSubresource(VB, MapMode.WriteDiscard, MapFlags.None);
data.Data.WriteRange(Vertex);
D3DContext.UnmapSubresource(VB, 0);
}

OpenGL : Draw curve between 3 points

Basically I wish to draw a curve between 3 points in openGL as the below image indicates. I've found a couple of segments of code which would be useful for drawing a bezier curve using 4 points but for 3 points I've had really no success.
From the definition of a Bezier curve you have the following formula (for each x, y component):
x(t) = (1-t)^3*p1x + 3*t*(1-t)^2*c1x + 3*t^2*(1-t)*c3x + t^3*p3x
y(t) = (1-t)^3*p1y + 3*t*(1-t)^2*c1y + 3*t^2*(1-t)*c3y + t^3*p3y
In your case you know the mid point (p2x,p2y). You can also assume that c1x and c2x have the same value; and that c1y and c2y also have the same value
So we have the following equations at t=0.5
p2x = (3/4)*c1x+(p1x+p3x)/8
p2y = (3/4)*c1y+(p1y+p3y)/8
which are solved for c1x=c2x and c1y=c2y with
c1x = c2x = -(p1x-8*p2x+p3x)/6
c1y = c2y = -(p1y-8*p2y+p3y)/6
to give the final Bezier equation to use in terms of points (p1x,p1y), (p2x,p2y) and (p3x,p3y):
x(t) = (1-t)^3 * [p1x]
+ 3*t*(1-t)^2 * [-(p1x-8*p2x+p3x)/6]
+ 3*t^2*(1-t) * [-(p1x-8*p2x+p3x)/6]
+ t^3 * [p3x]
y(t) = (1-t)^3 * [p1y]
+ 3*t*(1-t)^2 * [-(p1y-8*p2y+p3y)/6]
+ 3*t^2*(1-t) * [-(p1y-8*p2y+p3y)/6]
+ t^3 * [p3y]
Summary
Try the four control points
( p1x, p1y )
( -(p1x-8*p2x+p3x)/6, -(p1y-8*p2y+p3y)/6 )
( -(p1x-8*p2x+p3x)/6, -(p1y-8*p2y+p3y)/6 )
( p3x, p3y )
Here is an example I made with p1=(0,0), p2=(2,2) and p3=(4,-1). I calculated the following control points
( 0, 0 )
( 2, 17/6 )
( 2, 17/6 )
( 4, -1)
with the results shown below:
Sounds like you want a Hermite spline.

Resources