i'm stuck for days to calculate the velocity of a mouvement so i'll try to more explain my problem.
i have to applicate an approache which allows to detect fall with kinect SDK and VS c#.
this approche takes as input 3 dimensions of a 3Box, built from the coordinates of skeleton joints.
these dimensions are:
W = |xMin - xMax|;
H = |yMin - yMax|;
D = |zMin - zMax|;
with xMin, xMax, yMin, yMax, zMin, zMax the minimum and the maximum of coordinates in all the tracked joints.
At this point, this is not the problem.. i already calculated all these values:
List<Joint> JointList = new List<Joint>();
List<double> JCx = new List<double>();
List<double> JCy = new List<double>();
List<double> JCz = new List<double>();
// define the min and max of coordinates as the filed of view of kinect
private double xMin = 2.2;
private double xMax = -2.2;
private int framecounter = 0;
private double yMin = 1.6;
private double yMax = -1.6;
private double zMin = 4;
private double zMax = 0;
Skeleton first = GetFirstSkeleton(allFramesReadyEventArgs);
if (first == null) // if no skeleton
{
txtP.Text = "No One";
return;
}
else
{
txtP.Text = "Yes";
skeletonDetected = true;
/// define all joints
Joint Head = first.Joints[JointType.Head];
JointList.Add(Head);
Joint SC = first.Joints[JointType.ShoulderCenter];
JointList.Add(SC);
Joint SL = first.Joints[JointType.ShoulderLeft];
JointList.Add(SL);
Joint SR = first.Joints[JointType.ShoulderRight];
JointList.Add(SR);
Joint EL = first.Joints[JointType.ElbowLeft];
JointList.Add(EL);
Joint ER = first.Joints[JointType.ElbowRight];
JointList.Add(ER);
Joint WL = first.Joints[JointType.WristLeft];
JointList.Add(WL);
Joint WR = first.Joints[JointType.WristRight];
JointList.Add(WR);
Joint HandL = first.Joints[JointType.HandLeft];
JointList.Add(HandL);
Joint HandR = first.Joints[JointType.HandRight];
JointList.Add(HandR);
Joint Spine = first.Joints[JointType.Spine];
JointList.Add(Spine);
Joint HipC = first.Joints[JointType.HipCenter];
JointList.Add(HipC);
Joint HipL = first.Joints[JointType.HipLeft];
JointList.Add(HipL);
Joint HipR = first.Joints[JointType.HipRight];
JointList.Add(HipR);
Joint KL = first.Joints[JointType.KneeLeft];
JointList.Add(KL);
Joint KR = first.Joints[JointType.KneeRight];
JointList.Add(KR);
Joint AnkL = first.Joints[JointType.AnkleLeft];
JointList.Add(AnkL);
Joint AnkR = first.Joints[JointType.AnkleRight];
JointList.Add(AnkR);
Joint FL = first.Joints[JointType.FootLeft];
JointList.Add(FL);
Joint FR = first.Joints[JointType.FootRight];
JointList.Add(FR);
// calculate x, y and z coordinates for each joint and
// put it into 3 different lists
foreach (Joint j in JointList)
{
if (j.TrackingState == JointTrackingState.Tracked)
jx = j.Position.X;
JCx.Add(jx);
jy = j.Position.Y;
JCy.Add(jy);
jz = j.Position.Z;
JCz.Add(jz);
foreach (double f in JCx)
{
if (f < xMin)
xMin = f;
else if (f > xMax)
xMax = f;
}
foreach (double f in JCy)
{
if (f < yMin)
yMin = f;
else if (f > yMax)
yMax = f;
}
foreach (double f in JCz)
{
if (f < zMin)
zMin = f;
else if (f > zMax)
zMax = f;
}
}
txtminx.Text = xMin.ToString();
txtmaxx.Text = xMax.ToString();
txtminy.Text = yMin.ToString();
txtmaxy.Text = yMax.ToString();
txtminz.Text = zMin.ToString();
txtmaxz.Text = zMax.ToString();
//calculate the 3 dimensions of the Box and the diagonal WD
double W = System.Math.Abs(xMin - xMax);
double H = System.Math.Abs(yMin - yMax);
double D = System.Math.Abs(zMin - zMax);
double WD = System.Math.Sqrt(Math.Pow(W0, 2) + Math.Pow(D0, 2));
The problem is when i have to calculate the velocity of the box dimensions vH and vWD .
vH = (Hi - H0) /(Ti- T0);
vWD = (WDi- WD0) /(Ti-T0);
i tried to use DateTime.UtcNow and Stopwatch to calculate the time spend
DateTime T0 = DateTime.UtcNow;
Stopwatch _stopwatch = Stopwatch.StartNew();
DateTime Ti = DateTime.UtcNow;
but i don't know how to get H value in a first time and in a second also i'm not sure if this methode will give me real result.
Can anyone help me ?
Thanks in advance
I did something similar in an application.
I started a StopWatch when the application started:
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
int msNow;
int msPast;
int dif;
TimeSpan currentTime;
TimeSpan lastTime = new TimeSpan(0);
public GaitAnalyzer()
{
stopWatch.Start();
}
Then you just have to do something like this:
currentTime = stopWatch.Elapsed;
msNow = currentTime.Seconds * 1000 + currentTime.Milliseconds;
if(lastTime.Ticks != 0)
{
msPast = lastTime.Seconds * 1000 + lastTime.Milliseconds;
dif = msNow - msPast;
}
lastTime = currentTime;
Related
I've been trying to write a program that can render 4D lines, the specific function doing this gets the lines already rotated, and the function attempts to clip the lines at planes z = p and w = p if needed, and then draw the line to the screen.
I think that I am doing at least most of this properly, however I am unsure, and not having much experience viewing the fourth dimension I cannot tell what might be a visual bug, or what is actually how it should be rendered.
The function first loads a line into two variables, each is one of the two endpoints of the line. If both points are beyond clippl (the clipping plane variable) for z = clippl and w = clippl, it then applies perspective transformation to them, and subsequently renders a line on the screen correspondingly.
If certain logic is met for the points, the function goes through a process of clipping them, and then continues the same as it would outside the clipping planes.
The location of the camera is held in the variables Ox, Oy, Oz, Ow at the beginning of the full program.
I can't tell if I've done this properly, can anyone tell me if this works right as a 4D perspective projection from a first person camera?
EDIT: I've added points to the rendering list that are at the corners of the cube I'm rendering, and it seems to show that there is in fact some problem with the line clipping, as I am fairly certain that the points are rendering properly, and there is not always a line showing up at it. Could the problem have to do with the w = p clip?
Here's the function, the program uses p5.js:
function drawPLines(P){
var lA,lB;
for(var i=0;i<P.length;i++){
lA = [P[i][0],P[i][1],P[i][2],P[i][3]];
lB = [P[i][4],P[i][5],P[i][6],P[i][7]];
//X: ( x*VS+(width*0.5)+(ox*VS) )
//Y: ( y*VS+(height*0.5)+(oy*VS) )
//x: (XV[0]*P[i][0])+(YV[0]*P[i][1])+(ZV[0]*P[i][2])+(WV[0]*P[i][3])
//y: (XV[1]*P[i][0])+(YV[1]*P[i][1])+(ZV[1]*P[i][2])+(WV[1]*P[i][3])
var x0,y0,x1,y1;
//x0 = (XV[0]*lA[0])+(YV[0]*lA[1])+(ZV[0]*lA[2])+(WV[0]*lA[3]);
//y0 = (XV[1]*lA[0])+(YV[1]*lA[1])+(ZV[1]*lA[2])+(WV[1]*lA[3]);
//new rendering pipeline
//old rendering pipeline
if(lA[2]>clippl&&lB[2]>clippl&&lA[3]>clippl&&lB[3]>clippl){
x0 = XV[0]*lA[0];
y0 = YV[1]*lA[1];
x0 = (x0/lA[3])/(lA[2]/lA[3]);
y0 = (y0/lA[3])/(lA[2]/lA[3]);
//console.log(y);
x0 = ( x0*VS+(width*0.5)+(ox*VS) );
y0 = ( y0*VS+(height*0.5)+(oy*VS) );
//x1 = (XV[0]*lB[0])+(YV[0]*lB[1])+(ZV[0]*lB[2])+(WV[0]*lB[3]);
//y1 = (XV[1]*lB[0])+(YV[1]*lB[1])+(ZV[1]*lB[2])+(WV[1]*lB[3]);
x1 = XV[0]*lB[0];
y1 = YV[1]*lB[1];
x1 = (x1/lB[3])/(lB[2]/lB[3]);
y1 = (y1/lB[3])/(lB[2]/lB[3]);
//console.log(y);
x1 = ( x1*VS+(width*0.5)+(ox*VS) );
y1 = ( y1*VS+(height*0.5)+(oy*VS) );
stroke([P[i][8],P[i][9],P[i][10],P[i][11]]);
line(x0,y0,x1,y1);
}else if((lA[2]>clippl||lA[3]>clippl||lB[2]>clippl||lB[3]>clippl)){
var V = 0;
var zV = 0;
var wV = 0;
//var oV = 0;
if(lA[2]>clippl&&lA[3]>clippl){
V++;
}else if(lA[2]>clippl&&lA[3]<=clippl){
zV++;
}else if(lA[2]<=clippl&&lA[3]>clippl){
wV++;
}/*else{
oV++;
}*/
if(lB[2]>clippl&&lB[3]>clippl){
V++;
}else if(lB[2]>clippl&&lB[3]<=clippl){
zV++;
}else if(lB[2]<=clippl&&lB[3]>clippl){
wV++;
}/*else{
oV++;
}*/
if((V==1)||(wV==1&&(V==1||zV==1))||(zV==1&&(V==1||wV==1))){
var lin = lB;
var out = lA;
if(lA[2]<=clippl){
out = lB;
lin = lA;
}
if(lin[2]<=clippl){
lin = [((((lA[0]-lB[0])*clippl)-((lA[0]-lB[0])*lB[2]))/(lA[2]-lB[2]))+lB[0],((((lA[1]-lB[1])*clippl)-((lA[1]-lB[1])*lB[2]))/(lA[2]-lB[2]))+lB[1],clippl,((((lA[3]-lB[3])*clippl)-((lA[3]-lB[3])*lB[2]))/(lA[2]-lB[2]))+lB[3]];
}
if((lA[2]-lB[2])!==0){
lA = lin;
lB = out;
}
lin = lA;
out = lB;
if(lB[3]<=clippl){
out = lA;
lin = lB;
}
if(lin[3]<=clippl){
lin = [((((lA[0]-lB[0])*clippl)-((lA[0]-lB[0])*lB[3]))/(lA[3]-lB[3]))+lB[0],((((lA[1]-lB[1])*clippl)-((lA[1]-lB[1])*lB[3]))/(lA[3]-lB[3]))+lB[1],((((lA[2]-lB[2])*clippl)-((lA[2]-lB[2])*lB[3]))/(lA[3]-lB[3]))+lB[2],clippl];
//alert(lin);
//alert(out);
}
if((lA[3]-lB[3])!==0){
lA = lin;
lB = out;
}
if(lA[2]>clippl||lB[2]>clippl||lA[3]>clippl||lB[3]>clippl){
x0 = XV[0]*lA[0];
y0 = YV[1]*lA[1];
x0 = (x0/lA[3])/(lA[2]/lA[3]);
y0 = (y0/lA[3])/(lA[2]/lA[3]);
//console.log(y);
x0 = ( x0*VS+(width*0.5)+(ox*VS) );
y0 = ( y0*VS+(height*0.5)+(oy*VS) );
//x1 = (XV[0]*lB[0])+(YV[0]*lB[1])+(ZV[0]*lB[2])+(WV[0]*lB[3]);
//y1 = (XV[1]*lB[0])+(YV[1]*lB[1])+(ZV[1]*lB[2])+(WV[1]*lB[3]);
x1 = XV[0]*lB[0];
y1 = YV[1]*lB[1];
x1 = (x1/lB[3])/(lB[2]/lB[3]);
y1 = (y1/lB[3])/(lB[2]/lB[3]);
//console.log(y);
x1 = ( x1*VS+(width*0.5)+(ox*VS) );
y1 = ( y1*VS+(height*0.5)+(oy*VS) );
stroke([P[i][8],P[i][9],P[i][10],P[i][11]]);
line(x0,y0,x1,y1);
}
}
}
}
}
You can see the full program at https://editor.p5js.org/hpestock/sketches/Yfagz4Bz3
First, a picture:
Column A is my source data, 50 points.
Column C and D are the SMA calculated with numpy and mathdotnet.com, respectively, with a window of 15.
Column F is the delta.
As we can see, about halfway, the data becomes identical, but the first half is not. I do not understand why, and, more importantly, do not know what to trust.
So I got from SO an optimized version of the SMA and ran the data through it.
The code is here:
private static NDArray SMA(this NDArray Data, int Period)
{
var Length = Data.len;
// calculate the moving average
var Buffer = new double[Period];
var Output = new double[Length];
var CurrentIndex = 0;
for (var i = 0; i < Length; i++)
{
Buffer[CurrentIndex] = Data.GetDouble(i) / Period;
var MA = 0.0;
for (var j = 0; j < Period; j++)
{
MA += Buffer[j];
}
Output[i] = MA;
CurrentIndex = (CurrentIndex + 1) % Period;
}
var R = new ArraySegment<double>(Output, Period - 1, Length - Period + 1);
return new NDArray(R.ToArray());
}
It is using NumSharp, the .net port of numpy, to hold the source array.
While it is all different code, the C# code and python numpy output the same results (differences happen after the 12th decimal point, so we can consider them identical).
This points out to mathdotnet.com being different; so I guess I can trust the numpy / C# versions more.
Are there different variations of the SMA that could cause this? or something obvious I don't see?
I have put all the data here: https://pastebin.com/WgYJUUJF
Edit:
Here is the numpy code:
import numpy as np
def calcSma(data, smaPeriod):
j = next(i for i, x in enumerate(data) if x is not None)
our_range = range(len(data))[j + smaPeriod - 1:]
empty_list = [None] * (j + smaPeriod - 1)
sub_result = [np.mean(data[i - smaPeriod + 1: i + 1]) for i in our_range]
return np.array(empty_list + sub_result)
def calcSma2(data_set, periods=3):
weights = np.ones(periods) / periods
return np.convolve(data_set, weights, mode='valid')
a = np.array([1.1282553063375, 1.13157696082132, 1.13275406120136, 1.1332879715733, 1.12761933580452, 1.12621836040801, 1.12282485875706, 1.12265572041877, 1.13094386506532, 1.12320520490577, 1.12427293064877, 1.1328332027022, 1.13099445663901, 1.12843355605048, 1.13002750724853, 1.12843355605048, 1.13099445663901, 1.12709476494142, 1.12684879712348, 1.12672349888807, 1.12600933402474, 1.13112070248549, 1.12985951088976, 1.12822416032659, 1.12471789559362, 1.12651004224413, 1.12442669033881, 1.12334638977164, 1.12714333124378, 1.1312233808195, 1.12713229372575, 1.128255040952, 1.12585669781931, 1.12763457442902, 1.12470631424376, 1.12223443223443, 1.12506842815956, 1.12691187181355, 1.12385654130971, 1.13026344596074, 1.12237927400894, 1.1245915922457, 1.13088395780284, 1.13211944646759, 1.12590649028825, 1.12829127560895, 1.11876736364966, 1.12222667492441, 1.12169543369019, 1.12199031071285])
b = calcSma(a, 15)
c = calcSma2(a, 15)
print b
print "----------------------------------"
print c
and here is the mathdotnet one:
var data = Vector<double>.Build.Dense(new[] { 1.1282553063375, 1.13157696082132, 1.13275406120136, 1.1332879715733, 1.12761933580452, 1.12621836040801, 1.12282485875706, 1.12265572041877, 1.13094386506532, 1.12320520490577, 1.12427293064877, 1.1328332027022, 1.13099445663901, 1.12843355605048, 1.13002750724853, 1.12843355605048, 1.13099445663901, 1.12709476494142, 1.12684879712348, 1.12672349888807, 1.12600933402474, 1.13112070248549, 1.12985951088976, 1.12822416032659, 1.12471789559362, 1.12651004224413, 1.12442669033881, 1.12334638977164, 1.12714333124378, 1.1312233808195, 1.12713229372575, 1.128255040952, 1.12585669781931, 1.12763457442902, 1.12470631424376, 1.12223443223443, 1.12506842815956, 1.12691187181355, 1.12385654130971, 1.13026344596074, 1.12237927400894, 1.1245915922457, 1.13088395780284, 1.13211944646759, 1.12590649028825, 1.12829127560895, 1.11876736364966, 1.12222667492441, 1.12169543369019, 1.12199031071285 });
var sma = Vector<double>.Build.Dense(data.MovingAverage(15).Skip(14).ToArray());
var s = sma.Aggregate(string.Empty, (Current, v) => Current + $"{v}, ");
Console.WriteLine(s);
I am planning to build an antenna tracker. I need to get bearing and tilt from GPS point A with altitude and GPS point B with altitude.
This is the example points:
latA = 39.099912
lonA = -94.581213
altA = 273.543
latB = 38.627089
lonB = -90.200203
altB = 1380.245
I've already got the formula for horizontal bearing and it gives me 97.89138167122422
This is the code:
function toRadian(num) {
return num * (Math.PI / 180);
}
function toDegree(num) {
return num * (180 / Math.PI);
}
function getHorizontalBearing(fromLat, fromLon, toLat, toLon) {
fromLat = toRadian(fromLat);
fromLon = toRadian(fromLon);
toLat = toRadian(toLat);
toLon = toRadian(toLon);
let dLon = toLon - fromLon;
let x = Math.tan(toLat / 2 + Math.PI / 4);
let y = Math.tan(fromLat / 2 + Math.PI / 4);
let dPhi = Math.log(x / y);
if (Math.abs(dLon) > Math.PI) {
if (dLon > 0.0) {
dLon = -(2 * Math.PI - dLon);
} else {
dLon = (2 * Math.PI + dLon);
}
}
return (toDegree(Math.atan2(dLon, dPhi)) + 360) % 360;
}
let n = getHorizontalBearing(39.099912, -94.581213, 38.627089, -90.200203);
console.info(n);
But I don't know how to find the tilt angle. Anyone could help me?
I think I got the answer after searching around.
This is the complete code, if you think this is wrong, feel free to correct me.
function toRadian(num) {
return num * (Math.PI / 180);
}
function toDegree(num) {
return num * (180 / Math.PI);
}
// North is 0 degree, South is 180 degree
function getHorizontalBearing(fromLat, fromLon, toLat, toLon, currentBearing) {
fromLat = toRadian(fromLat);
fromLon = toRadian(fromLon);
toLat = toRadian(toLat);
toLon = toRadian(toLon);
let dLon = toLon - fromLon;
let x = Math.tan(toLat / 2 + Math.PI / 4);
let y = Math.tan(fromLat / 2 + Math.PI / 4);
let dPhi = Math.log(x / y);
if (Math.abs(dLon) > Math.PI) {
if (dLon > 0.0) {
dLon = -(2 * Math.PI - dLon);
} else {
dLon = (2 * Math.PI + dLon);
}
}
let targetBearing = (toDegree(Math.atan2(dLon, dPhi)) + 360) % 360;
return targetBearing - currentBearing;
}
// Horizon is 0 degree, Up is 90 degree
function getVerticalBearing(fromLat, fromLon, fromAlt, toLat, toLon, toAlt, currentElevation) {
fromLat = toRadian(fromLat);
fromLon = toRadian(fromLon);
toLat = toRadian(toLat);
toLon = toRadian(toLon);
let fromECEF = getECEF(fromLat, fromLon, fromAlt);
let toECEF = getECEF(toLat, toLon, toAlt);
let deltaECEF = getDeltaECEF(fromECEF, toECEF);
let d = (fromECEF[0] * deltaECEF[0] + fromECEF[1] * deltaECEF[1] + fromECEF[2] * deltaECEF[2]);
let a = ((fromECEF[0] * fromECEF[0]) + (fromECEF[1] * fromECEF[1]) + (fromECEF[2] * fromECEF[2]));
let b = ((deltaECEF[0] * deltaECEF[0]) + (deltaECEF[2] * deltaECEF[2]) + (deltaECEF[2] * deltaECEF[2]));
let elevation = toDegree(Math.acos(d / Math.sqrt(a * b)));
elevation = 90 - elevation;
return elevation - currentElevation;
}
function getDeltaECEF(from, to) {
let X = to[0] - from[0];
let Y = to[1] - from[1];
let Z = to[2] - from[2];
return [X, Y, Z];
}
function getECEF(lat, lon, alt) {
let radius = 6378137;
let flatteningDenom = 298.257223563;
let flattening = 0.003352811;
let polarRadius = 6356752.312106893;
let asqr = radius * radius;
let bsqr = polarRadius * polarRadius;
let e = Math.sqrt((asqr-bsqr)/asqr);
// let eprime = Math.sqrt((asqr-bsqr)/bsqr);
let N = getN(radius, e, lat);
let ratio = (bsqr / asqr);
let X = (N + alt) * Math.cos(lat) * Math.cos(lon);
let Y = (N + alt) * Math.cos(lat) * Math.sin(lon);
let Z = (ratio * N + alt) * Math.sin(lat);
return [X, Y, Z];
}
function getN(a, e, latitude) {
let sinlatitude = Math.sin(latitude);
let denom = Math.sqrt(1 - e * e * sinlatitude * sinlatitude);
return a / denom;
}
let n = getHorizontalBearing(39.099912, -94.581213, 39.099912, -94.588032, 0.00);
console.info("Horizontal bearing:\t", n);
let m = getVerticalBearing(39.099912, -94.581213, 273.543, 39.099912, -94.588032, 873.543, 0.0);
console.info("Vertical bearing:\t", m);
Don Cross's javascript code produces good results. It takes into consideration the curvature of the earth plus the fact that the earth is oblate.
Example:
var elDegrees = calculateElevationAngleCosineKitty(
{latitude: 35.346257, longitude: -97.863801, altitudeMetres: 10},
{latitude: 34.450545, longitude: -96.500167, altitudeMetres: 9873}
);
console.log("El: " + elDegrees);
/***********************************
Code by Don Cross at cosinekitty.com
http://cosinekitty.com/compass.html
************************************/
function calculateElevationAngleCosineKitty(source, target)
{
var oblate = true;
var a = {'lat':source.latitude, 'lon':source.longitude, 'elv':source.altitudeMetres};
var b = {'lat':target.latitude, 'lon':target.longitude, 'elv':target.altitudeMetres};
var ap = LocationToPoint(a, oblate);
var bp = LocationToPoint(b, oblate);
var bma = NormalizeVectorDiff(bp, ap);
var elevation = 90.0 - (180.0 / Math.PI)*Math.acos(bma.x*ap.nx + bma.y*ap.ny + bma.z*ap.nz);
return elevation;
}
function NormalizeVectorDiff(b, a)
{
// Calculate norm(b-a), where norm divides a vector by its length to produce a unit vector.
var dx = b.x - a.x;
var dy = b.y - a.y;
var dz = b.z - a.z;
var dist2 = dx*dx + dy*dy + dz*dz;
if (dist2 == 0) {
return null;
}
var dist = Math.sqrt(dist2);
return { 'x':(dx/dist), 'y':(dy/dist), 'z':(dz/dist), 'radius':1.0 };
}
function EarthRadiusInMeters (latitudeRadians) // latitude is geodetic, i.e. that reported by GPS
{
// http://en.wikipedia.org/wiki/Earth_radius
var a = 6378137.0; // equatorial radius in meters
var b = 6356752.3; // polar radius in meters
var cos = Math.cos (latitudeRadians);
var sin = Math.sin (latitudeRadians);
var t1 = a * a * cos;
var t2 = b * b * sin;
var t3 = a * cos;
var t4 = b * sin;
return Math.sqrt ((t1*t1 + t2*t2) / (t3*t3 + t4*t4));
}
function GeocentricLatitude(lat)
{
// Convert geodetic latitude 'lat' to a geocentric latitude 'clat'.
// Geodetic latitude is the latitude as given by GPS.
// Geocentric latitude is the angle measured from center of Earth between a point and the equator.
// https://en.wikipedia.org/wiki/Latitude#Geocentric_latitude
var e2 = 0.00669437999014;
var clat = Math.atan((1.0 - e2) * Math.tan(lat));
return clat;
}
function LocationToPoint(c, oblate)
{
// Convert (lat, lon, elv) to (x, y, z).
var lat = c.lat * Math.PI / 180.0;
var lon = c.lon * Math.PI / 180.0;
var radius = oblate ? EarthRadiusInMeters(lat) : 6371009;
var clat = oblate ? GeocentricLatitude(lat) : lat;
var cosLon = Math.cos(lon);
var sinLon = Math.sin(lon);
var cosLat = Math.cos(clat);
var sinLat = Math.sin(clat);
var x = radius * cosLon * cosLat;
var y = radius * sinLon * cosLat;
var z = radius * sinLat;
// We used geocentric latitude to calculate (x,y,z) on the Earth's ellipsoid.
// Now we use geodetic latitude to calculate normal vector from the surface, to correct for elevation.
var cosGlat = Math.cos(lat);
var sinGlat = Math.sin(lat);
var nx = cosGlat * cosLon;
var ny = cosGlat * sinLon;
var nz = sinGlat;
x += c.elv * nx;
y += c.elv * ny;
z += c.elv * nz;
return {'x':x, 'y':y, 'z':z, 'radius':radius, 'nx':nx, 'ny':ny, 'nz':nz};
}
/***********************
END cosinekitty.com code
************************/
So I have an image which contains a tile-sheet, where each tile is approx 16 pixels wide, and high. But there spaced out with a transparent spacer between each tile.
Like so:
But this is ugly, and makes displaying the sprites in the program annoying, not to mention it wastes valuable image space. Is there any easy (Besides me manually using Photoshop to move each individual tile) way to make it look like this?
I looked through Photoshop macros, as-well as other programs and I diden't seem to find anything that would directly do this.
Google also suggests I go to home-depo and get tile caulk remover.
Try this snippet. As you said, it assumes tiles are always going to be 16 pixels. Top left one is in the correct position and a single pixel gap. The script assumes the document will opened with the layer containing your tiles set as the active layer.
#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
var gap = 1;
var tileSize = 16;
var doc = app.activeDocument.duplicate();
var sourceLyr = doc.activeLayer;
var xTilePosition = 0;
var yTilePosition = 0;
for (var x = 0; x < sourceLyr.bounds[2]; x = x+ tileSize + 1 ) {
for (var y = 0; y < sourceLyr.bounds[3]; y = y + tileSize + 1) {
if (x > 0 || y > 0) {
app.activeDocument = doc;
doc.activeLayer = sourceLyr;
selRegion = Array(Array(x, y),
Array(x + tileSize, y),
Array(x + tileSize, y + tileSize),
Array(x, y + tileSize),
Array(x, y))
doc.selection.select(selRegion);
var dx = x - (xTilePosition * tileSize);
var dy = y - (yTilePosition * tileSize);
doc.selection.translate(0 - dx, 0 - dy);
}
yTilePosition ++;
}
xTilePosition++;
yTilePosition = 0;
}
asking about speed or optimize the code
the kernel for sobel edge detection for gray img
When I run the program without any process only show input video and output(same as input) the frame per secounds fps=70 but when process down to 20 (process using GPU kernel for sobel)
Does anyone have an idea of how to speed up this code? I used local memory instead of global memory but the change is small.
How can I make all work items process the image?
sobel kernel
__kernel void hello_kernel(const __global uchar *input, __global uchar *output,const uint width,const uint height)
{
int x = get_global_id(0);
int y = get_global_id(1);
int index = width * y + x;
float a,b,c,d,e,f,g,h,i;
float8 v;
float sobelX = 0;
float sobelY = 0;
//if(index > width && index < (height*width)-width && (index % width-1) > 0 && (index % width-1) < width-1){
a = input[index-1-width] * -1.0f;
b =input[index-0-width] * 0.0f;
c = input[index+1-width] * +1.0f;
d = input[index-1] * -2.0f;
e = input[index-0] * 0.0f;
f = input[index+1] * +2.0f;
g = input[index-1+width] * -1.0f;
h = input[index-0+width] * 0.0f;
i = input[index+1+width] * +1.0f;
sobelX = a+b+c+d+e+f+g+h+i;
a = input[index-1-width] * -1.0f;
b = input[index-0-width] * -2.0f;
c = input[index+1-width] * -1.0f;
d = input[index-1] * 0.0f;
e = input[index-0] * 0.0f;
f = input[index+1] * 0.0f;
g = input[index-1+width] * +1.0f;
h = input[index-0+width] * +2.0f;
i = input[index+1+width] * +1.0f;
sobelY = a+b+c+d+e+f+g+h+i;
output[index] = sqrt(pow(sobelX,2) + pow(sobelY,2));
}