I am trying to implement the equations presented here regarding finding a point on a given perpendicular distance from a line. Unfortunately the lines I receive are not straight. Is this due to me mixing Lat/long with regular x/y coordinates or have I done something else wrong?!
double distPoint = 0.02;
double latDiff = temp2.Latitude - temp.Latitude;
double longDiff = temp2.Longitude - temp.Longitude;
double length = Math.Sqrt(latDiff * latDiff + longDiff * longDiff);
double uLat = latDiff / length;
double uLong = longDiff / length;
double newLat1 = temp2.Latitude + (distPoint / 2) * uLat;
double newLong1 = temp2.Longitude - (distPoint / 2) * uLong;
double newLat2 = temp2.Latitude - (distPoint / 2) * uLat;
double newLong2 = temp2.Longitude + (distPoint / 2) * uLong;
Have changed the code now, and the variable names. Still receiving the fault :-(
double dist = 0.02;
double latDiff = secondTestPoint.Latitude - firstTestPoint.Latitude;
double longDiff = secondTestPoint.Longitude - firstTestPoint.Longitude;
double length = Math.Sqrt(latDiff * latDiff + longDiff * longDiff);
double uLat = latDiff / length;
double uLong = longDiff / length;
double newLat1 = secondTestPoint.Latitude + (dist / 2) * uLong;
double newLong1 = secondTestPoint.Longitude - (dist / 2) * uLat;
double newLat2 = secondTestPoint.Latitude - (dist / 2) * uLong;
double newLong2 = secondTestPoint.Longitude + (dist / 2) * uLat;
Here are the variable values:
latDiff = -0.0046187639236450195
longDiff = -0.0058203935623168945
length = 0.0074303405980227239
uLat = -0.62160864131505777
uLong = -0.78332796263279647
newLat1 = 58.39273776863341
newLong1 = 15.558675147558933
newLat2 = 58.408404327886061
newLong2 = 15.546242974732632
UPDATE: I have come to the conclusion that the fault is due to lat/long issues. It seems reasonable that it would generate faults to think that the lat/long are equivalent to squares when they in fact are not. Especially when working with northern europe.
At such a small scale, the difference between x/y and lat/long isn't relevant. You've done something else wrong; what you should have is:
double distPoint = 0.02;
double latDiff = temp2.Latitude - temp.Latitude;
double longDiff = temp2.Longitude - temp.Longitude;
double length = Math.Sqrt(latDiff * latDiff + > longDiff * longDiff);
double uLat = latDiff / length;
double uLong = longDiff / length;
double newLat1 = temp2.Latitude + (distPoint / 2) * uLong;
double newLong1 = temp2.Longitude - (distPoint / 2) * uLat;
double newLat2 = temp2.Latitude - (distPoint / 2) * uLong;
double newLong2 = temp2.Longitude + (distPoint / 2) * uLat;
That is, the vector (uLat, uLong) is a unit vector in the direction of your line, so a perpendicular unit vector is (uLong, -uLat) - note that the coordinates swapped position, in addition to one being negated.
In the formula you linked, the last 4 lines have a multiplication sequence as:
[dy, dx, dy, dx] == [uLong, uLat, uLong, uLat]
however you've used:
[dx, dy, dx, dy] == [uLat, uLong, uLat, uLong]
Your last 4 lines should be this:
double newLat1 = temp2.Latitude + (distPoint / 2) * uLong; //dy appears first
double newLong1 = temp2.Longitude - (distPoint / 2) * uLat; //then dx
double newLat2 = temp2.Latitude - (distPoint / 2) * uLong;
double newLong2 = temp2.Longitude + (distPoint / 2) * uLat;
Latitude and Longitude degrees are not 1:1.
Related
I am working on a game engine, and I ran into this problem when creating a position rotation scale component. The position and scale work just fine, but when I recalculate the rotation quaternion it will invert itself (i.e. point in the opposite direction). What we do is simple -
Whenever the parent quaternion is changed:
We rotate the parent accordingly - Fine
We calculate the child's local rotation (relative to parent) - Fine
We multiply the parent rotation by the child's local rotation - Not fine.
What we are doing is literally (q2/q1)*q2 -> q2*q1^-1*q2
I am using the http://www.technologicalutopia.com/sourcecode/xnageometry/quaternion.cs.htm implementation, where multiplying quaternions will rotate the first by the second, and dividing does the inverse.
I have spent weeks on this problem, so any help is appreciated. :)
There appears to be an error in the CreateFromRotationMatrix method code in the link you posted. My calculations show that all of the difference calculations have the wrong sign. The corrected code would be this, changes where annotated:
public static Quaternion CreateFromRotationMatrix(Matrix matrix)
{
double num8 = (matrix.M11 + matrix.M22) + matrix.M33;
Quaternion quaternion;
if (num8 > 0.0)
{
double num = (double)sqrt((double)(num8 + 1.0));
quaternion.W = num * 0.5;
num = 0.5 / num;
quaternion.X =-(matrix.M23 - matrix.M32) * num; // -
quaternion.Y =-(matrix.M31 - matrix.M13) * num; // -
quaternion.Z =-(matrix.M12 - matrix.M21) * num; // -
return quaternion;
}
if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
{
double num7 = (double)sqrt((double)(((1.0 + matrix.M11) - matrix.M22) - matrix.M33));
double num4 = 0.5 / num7;
quaternion.X = 0.5 * num7;
quaternion.Y = (matrix.M12 + matrix.M21) * num4;
quaternion.Z = (matrix.M13 + matrix.M31) * num4;
quaternion.W =-(matrix.M23 - matrix.M32) * num4; // -
return quaternion;
}
if (matrix.M22 > matrix.M33)
{
double num6 = (double)sqrt((double)(((1.0 + matrix.M22) - matrix.M11) - matrix.M33));
double num3 = 0.5 / num6;
quaternion.X = (matrix.M21 + matrix.M12) * num3;
quaternion.Y = 0.5 * num6;
quaternion.Z = (matrix.M32 + matrix.M23) * num3;
quaternion.W =-(matrix.M31 - matrix.M13) * num3; // -
return quaternion;
}
double num5 = (double)sqrt((double)(((1.0 + matrix.M33) - matrix.M11) - matrix.M22));
double num2 = 0.5 / num5;
quaternion.X = (matrix.M31 + matrix.M13) * num2;
quaternion.Y = (matrix.M32 + matrix.M23) * num2;
quaternion.Z = 0.5 * num5;
quaternion.W =-(matrix.M12 - matrix.M21) * num2; // -
return quaternion;
}
A sample run with a MATLAB mex file (qstuff) as a driver:
>> q2
q2 =
0.531932290454131 -0.391764141068189 0.538459173155997 0.523097137240767
>> qstuff('CreateFromRotationMatrix',qstuff('ToMatrix',q2))
ans =
0.531932290454131 0.391764141068189 -0.538459173155998 -0.523097137240767
>> qstuff('CreateFromRotationMatrixNew',qstuff('ToMatrix',q2))
ans =
0.531932290454131 -0.391764141068189 0.538459173155998 0.523097137240767
The original code doesn't reproduce the quaternion, but the corrected code does.
I just wrote this code to perform an iterative calculation. It finds the X,Y coordinates where an unknown parabola is tangent to a known circle. It is based on other iterative functions I've written that have worked flawlessly. I'm stumped as to what the issue is. Here is the code:
Public Function Jext(PA As Double, Xcl As Double, Ycl As Double, Ctr As Double, Rnl As Double, Finl As Double) As Double
Pi = 3.14159265358979
tol = 0.00000001
Dim x(20) As Double
Dim Yc(20) As Double
Dim Yp(20) As Double
Dim A(20) As Double
Dim Diff(20) As Double
Dim It As Integer
Dim hF As Double
Dim Sf As Double
'Xcl is the horizontal position of the root radius center line
'Ycl is the vertical position of the root radius center line
'Ctr is root radius. It's an approximation of the trochoid and is typically the cutter tip radius
'Rnl is the radius to the point where the load line intersects the tooth centerline. It is the apex of the parabola
'x is the horizontal position that is common to the parabola and circle. It is the independent variable
'Yc is the vertical position on the circle at point x
'Yp is the vertical position on the parabola at point x
'A is the leading term of the parabolic equation
'Diff is the calculated difference in vertical positions of circle and parabola
'Set initial guess values. x(0) is 5% of the radius (left edge of circle) and x(1) is 95% of the radius(bottom of the circle)
x(0) = (Xcl - Ctr) + 0.05 * Ctr
x(1) = (Xcl - Ctr) + 0.95 * Ctr
Yc(0) = Ycl - (Ctr ^ 2 - (x(0) - Xcl) ^ 2) ^ 0.5
Yc(1) = Ycl - (Ctr ^ 2 - (x(1) - Xcl) ^ 2) ^ 0.5
A(0) = Tan(WorksheetFunction.Acos((Xcl - x(0)) / Ctr) + Pi / 2) / (2 * x(0))
A(1) = Tan(WorksheetFunction.Acos((Xcl - x(1)) / Ctr) + Pi / 2) / (2 * x(1))
Yp(0) = A(0) * x(0) ^ 2 + Rnl
Yp(1) = A(1) * x(1) ^ 2 + Rnl
Diff(0) = Yp(0) - Yc(0)
Diff(1) = Yp(1) - Yc(1)
For It = 1 To 19 Step 1
x(It + 1) = x(It) - (Diff(It) - 0) * (x(It - 1) - x(It)) / (Diff(It - 1) - Diff(It))
Yc(It + 1) = Ycl - (Ctr ^ 2 - (x(It + 1) - Xcl) ^ 2) ^ 0.5
A(It + 1) = Tan(WorksheetFunction.Acos((Xcl - x(It + 1)) / Ctr) + Pi / 2) / (2 * x(It + 1))
Yp(It + 1) = A(It + 1) * x(It + 1) ^ 2 + Rnl
Diff(It + 1) = Yp(It + 1) - Yc(It + 1)
If Abs(Diff(It + 1)) < tol Then Exit For
Debug.Print Diff(It + 1)
Next It
hF = Rnl - Yp(t + 1)
Sf = 2 * x(t + 1)
Jext = 1 / (Cos(Finl) / Cos(PA) * (6 * hF / Sf ^ 2 - Tan(Finl) / Sf))
End Function
I put a stop at the "Next It" line to check the values as it went through the iterative loops. When I execute the code, all of the values are as expected and the value of Abs(Diff(It+1)) is not small enough to exit the for loop in the IF statement. I put the Debug.Print statement in there to make sure it was getting that far in the code and it did print Diff(It+1). So it executes everything to that point. Then when I continue the function it just stops and returns a #VALUE error in the spreadsheet. I've no idea why it won't continue the for loop. Anyone see something I've missed?
I am trying to display only one digit to the right of the decimal place unless that digit is a 0, then there would be no decimal place displayed. I am a beginner and I cannot use any complicated coding or conditional statements. This is my current code but it will not display any decimal places in any case.
#include<stdio.h>
#include<math.h>
#define PI 3.1415927
int main()
{
//Local Declarations
float radius;
float volume;
float SA;
float height;
int dec;
int Dec;
int dec1;
int dec2;
int Dec1;
int Dec2;
//Statements
printf("Enter the radius: ");
scanf("%f", &radius);
height = radius;
volume = PI * pow( radius, 2.0) * height;
SA = (2.0 * PI * pow( radius, 2.0)) + (2.0 * PI * radius * height);
dec = (volume - (int)volume) * 10.0;
dec1= 0.1 * (int)dec;
dec2 = (dec1 + 2) % (dec1 + 1);
Dec = (SA - (int)SA) * 10.0;
Dec1 = 0.1 * (int)Dec;
Dec2 = (Dec1 + 2) % (Dec1 + 1);
//Output
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
printf("\nVolume: %.*f\n",dec2, volume);
printf("Surface Area: %.*f\n",Dec2, SA);
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
return 0;
} //main
You are declaring your dec variables as integers. You should use float instead. Any operation cast to an integer will result in the loss of the decimal.
I would like to know if there is any possibility of representing the UML2 Boundary/Control/Entity symbols of a Sequence Diagram in UMLet ? (http://www.uml.org.cn/oobject/images/seq02.gif)
Do I have to write their java code myself or does it already exist somewhere ?
This is the snippet I used to create a boundary symbol in UMLet. You can alter it as needed.
int h = height - textHeight() * textlines.size();
int radius = h/2;
drawCircle(width-radius, radius, radius);
drawLine(0, 10, 0, h-10);
drawLine(0, radius, width-h, radius);
int y = textHeight()+5;
for(String textline : textlines) {
printCenter(textline, height-3);
}
Preview:
I am not sure whether you are referring to Sequence, or Sequence all-in-one.
While those new lifelines are not supported, you can easily add a custom element to the former. There is a nice and easy tutorial how to add a new element here http://www.umlet.com/ce/ce.htm
If you want to add it to the all-in-one, you would need to dive into the internals, since it would require also changes in the text parser.
So I sort of made some models based on Noah's own. It's far from being a professional thing, and is pretty dirty code, but it does the trick for some time, I guess. So if anyone ever gets the same problem as me before these symbols are better implemented in UMLet :
Entity :
int h = height - textHeight() * textlines.size();
int radius = h*2/5;
int w = radius*2 ;
double x = (width - w)/2 + radius ;
double y = h/10 + radius;
double x2 = x + radius/4 * Math.sqrt(3);
double y2 = y - radius/4 ;
drawCircle((int)x, (int) y, radius);
drawLine((int)x-radius , (int)y + radius , (int) x+ radius, (int) y+radius);
drawLine((int)x - radius , (int) y - 2*radius , (int) x + radius, (int) y - 2*radius);
for(String textline : textlines) {
printCenter(textline, h);
}
Control :
int h = height - textHeight() * textlines.size();
int radius = h*2/5;
int w = radius*2 ;
double x1 = (width - w)/2 + radius ;
double y1 = h/10;
double x2 = x1 + radius/4 * Math.sqrt(3);
double y2 = y1 - radius/4 ;
double x3 = x1 + radius/4 * Math.sqrt(3);
double y3 = y1 + radius/4;
drawCircle((int)x1, (int) y1+radius, radius);
drawLine((int)x1, (int) y1 , (int)x2, (int)y2);
drawLine((int)x1, (int) y1 , (int)x3, (int)y3);
int y = textHeight()+5;
for(String textline : textlines) {
printCenter(textline, h);
}
First of all, I am not looking to for points spaced uniformly around a circle, I know that has been answered many times. Instead, I have one point on a circle, and I need to find another that is a certain distance from it.
Here is an illustration :
The distance can be either between the two points (black dotted line), or the length of the circumference between the points (blue line), whatever is simplest (accuracy is not very important).
I know the following variables:
(green point x, y)
d
r
(centre point x, y)
So how can I find one of the red points?
So, basically you want to get intersection points of two circles:
The big one (BluePoint, radius = R)
A small one (GreenPoint, radius = D)
(Please excuse my amazing drawing skills :P)
I've at first tried to solve it myself, and fruitlessly wasted several sheets of paper.
Then I started googling and found an algorithm in other question.
Here is my Java implementation
double[][] getCircleIntersection(
double x0, double y0, double r0,
double x1, double y1, double r1) {
// dist of centers
double d = sqrt(sq(x0 - x1) + sq(y0 - y1));
if (d > r0 + r1) return null; // no intersection
if (d < abs(r0 - r1)) return null; // contained inside
double a = (sq(r0) - sq(r1) + sq(d)) / (2 * d);
double h = sqrt(sq(r0) - sq(a));
// point P2
double x2 = x0 + a * (x1 - x0) / d;
double y2 = y0 + a * (y1 - y0) / d;
// solution A
double x3_A = x2 + h * (y1 - y0) / d;
double y3_A = y2 - h * (x1 - x0) / d;
// solution B
double x3_B = x2 - h * (y1 - y0) / d;
double y3_B = y2 + h * (x1 - x0) / d;
return new double[][] {
{ x3_A, y3_A },
{ x3_B, y3_B }
};
}
// helper functions
double sq(double val) {
return Math.pow(val, 2);
}
double sqrt(double val) {
return Math.sqrt(val);
}
double abs(double val) {
return Math.abs(val);
}
This is how you would use it for the question situation:
double centerX = 0;
double centerY = 0;
double radius = 5;
double pointX = 10;
double pointY = 0;
double newPointDist = 5;
double[][] points = getCircleIntersection(centerX, centerY, radius, pointX, pointY, newPointDist);
System.out.println("A = [" + points[0][0] + " , " + points[0][3] + "]");
System.out.println("B = [" + points[1][0] + " , " + points[1][4] + "]");
Project your right red point down on both axes to get X and Y.
From there, you'll get 2 distinct right angle triangles:
Solutions: