Hellow it possible get angle two lines in react js, using svg, without using the svg set attribute?
already tried several tutorials of the stack but none really returned the angle between the two lines and yes only the angle in which the line is, I tried this.
findAngle(p0,p1,p2) {
var a = Math.pow(10,2) + Math.pow(100,2),
b = Math.pow(10,2) + Math.pow(10,2),
c = Math.pow(10,2) + Math.pow(70,2);
var aa = Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
console.log(aa);
}
obs: these values are in my two lines.
Based on this answer, you want something like this:
// helper function: make a point
function point(x,y){
return {'x':x,'y':y};
}
// helper function: get distance between points a and b (by Pythagoras)
function d(a,b) {
return Math.sqrt(d2(a,b));
}
// helper function: get square of distance between points a and b
function d2(a,b) {
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
// helper function: convert radians to degrees
function rad2deg(angleInRadians) {
return angleInRadians/(Math.PI/180);
}
// get the angle in degrees between ab and ac, using the cosine rule:
function angle_deg(a,b,c) {
return rad2deg(Math.acos((d2(a,b) + d2(a,c) - d2(c,b)) / (2 * d(a,b) * d(a,c))));
}
p0 = point(0,0);
p1 = point(1,0);
p2 = point(0,1);
console.log(angle_deg(p0,p1,p2)); // 90
Related
I know its a bit convoluted, but consider this hypothetical:
class test {
points = [[10,15]];
rotate (angle){
let deg = angle *= Math.PI/180; //degrees to radians
this.points.map((point, pointIndex) => point.map((value, axis) => this.points[pointIndex][axis] = axis === 0 ? (this.points[pointIndex][0]*Math.cos(deg)-this.points[pointIndex][1]*Math.sin(deg)):(this.points[pointIndex][1]*Math.cos(deg)+this.points[pointIndex][0]*Math.sin(deg))));
//This essentially maps the current points to their projections after rotating them by some angle
//It performs two different operations respective to the two different values in the nested array
}
}
let foo = new test;
foo.rotate(90);
console.log(foo.points);
Running this will return:
Array [ -15, -14.999999999999998 ]
Which, for arguments sake, is not the intended result.
At first I assumed it had something to do with the use of the "?" operator, but eliminating this and separating the outcomes into their own mapping:
class test {
points = [[10,15]];
rotate (angle){
let deg = angle *= Math.PI/180;
this.points.map((point, pointIndex) => this.points[pointIndex][0]=(this.points[pointIndex][0]*Math.cos(deg)-this.points[pointIndex][1]*Math.sin(deg)));
this.points.map((point, pointIndex) => this.points[pointIndex][1]=(this.points[pointIndex][1]*Math.cos(deg)+this.points[pointIndex][0]*Math.sin(deg)));
}
}
let foo = new test;
foo.rotate(90);
console.log(foo.points);
But this results in the same outcome. However, when running either of line by itself, which, because they are split, affects only the first or second element depending on which is eliminated, the accurate result is returned:
Array [ -15, 15 ] (if the second line is removed)
Array [ 10, 10.000000000000002 ] (if the first line is removed)
Both of which return the accurate value of their respective index. ([ -15, 10.000000000000002 ] is correct, taking the first element of the first array and the second of the second.)
For some reason, by running them in succession, something fails.
Thank you in advance.
Edit: The same issue occurs when using forEach().
You shouldn't access the current object inside an transformation.
class test {
points = [[10,15]];
rotate (angle){
let deg = angle * Math.PI/180; //degrees to radians
this.points = this.points.map((point) => {
let newPoint = [0,0];
newPoint[0] = point[0]*Math.cos(deg)-point[1]*Math.sin(deg);
newPoint[1] = point[1]*Math.cos(deg)+point[0]*Math.sin(deg);
return newPoint
})
//This essentially maps the current points to their projections after rotating them by some angle
//It performs two different operations respective to the two different values in the nested array
}
}
let foo = new test;
foo.rotate(90);
console.log(foo.points);
You are transforming one coordinate and then doing to operation for the other one with the new value (not the old one as you should). I think that's the problem.
class test {
points = [[10, 15]];
rotate (angle){
let radians = (Math.PI / 180) * angle,
cos = Math.cos(radians),
sin = Math.sin(radians);
this.points = this.points.map((p) => {
return [cos * p[0] + sin * p[1], cos * p[1] - sin * p[0]];
})
}
}
let foo = new test;
foo.rotate(90);
console.log(foo.points);
Link to jsFiddle
I am trying to "alter" the sin cos and tan function from Math object so it can accept recognize if it is a degree "d" or radians. I have an idea on how to do it but I do not know to do it without changing my main function
(function() {
var angle;
while (angle = parseFloat(readline())) {
print(Math.sin(angle, "d").toPrecision(5)); // degrees
print(Math.sin(angle).toPrecision(5)); // radians
print(Math.cos(angle, "d").toPrecision(5));
print(Math.cos(angle).toPrecision(5));
print(Math.tan(angle, "d").toPrecision(5));
print(Math.tan(angle).toPrecision(5));
}
})();
How do alter does function so they can accept the "d" argument I tried use Object.create and another things like JSON.parse(JSON.stringify(Math)); but it doesn't work I need to know how to deep copy Math
You can override Math (in a closure) with an object which inherits from Math:
(function(globalMath) {
// Overriding Math:
var Math = Object.create(globalMath);
// Enhancing trigonometric methods:
var trig = ['sin', 'cos', 'tan'];
for(var i=0; i<3; ++i)
Math[trig[i]] = (function(trigFunc){
return function(angle, d) {
if(d==="d") angle *= Math.PI / 180;
return trigFunc(angle);
};
})(globalMath[trig[i]]);
// Now you can use the enhanced methods:
Math.sin(Math.PI/6); // 0.5
Math.sin(30, 'd'); // 0.5
// You can also use original methods:
globalMath.sin(Math.PI/6); // 0.5
globalMath.sin(Math.PI/6, 'd'); // 0.5 ('d' is ignored)
// Math is a shortcut of globalMath for other methods:
Math.max(1,2); // 2
})(Math);
Everything's an Object in JavaScript, so you can re-write the native Math functions. But this is not recommended, as other commentators have said.
It's simpler to create your own function that converts to degrees internally, like this:
function sinDegrees(angle) {
return Math.sin(angle * (Math.PI / 180));
}
It could even be part of the Math object, if you want:
Math.sinDegrees = sinDegrees;
If you still want to modify the Math.sin function like that, then you can do this:
Math._sin = Math.sin; // save a ref. to the old sin
Math.sin = function sin(angle, type) {
if (type == 'd')
return Math._sin(angle * (Math.PI / 180));
else
return Math._sin(angle);
}
The better solution here is to have a toRad function. It looks very similar to your target code without breaking basic good practices (don't modify objects you didn't create).
function toRad(angle){
return angle * (Math.PI / 180);
}
print(Math.sin(toRad(angle)).toPrecision(5)); // degrees
print(Math.sin(angle).toPrecision(5)); // radians
print(Math.cos(toRad(angle)).toPrecision(5));
print(Math.cos(angle).toPrecision(5));
print(Math.tan(toRad(angle)).toPrecision(5));
print(Math.tan(angle).toPrecision(5));
This also saves you from defining custom versions of each function.
Using this thread (Calculate the shortest way to rotate, right or left?) I created a function that returns a positive or negative rotation angle. Problem is, it seems really inefficient. Can anyone help? (for clarity purposes, i've spelled out the var names and created helper functions.)
function getRotation(center, target, heading) {
var north = new point(center.x(), center.y() + 10);
/* I tried to calculate these seperately so I dont have to calc the distance so many tiems but couldnt come up with anything...
var distCenterToHeading = getDist(center, heading);
var distCenterToTarget = getDist(center, target);
var distTargetToHeading = getDist(target, heading);
var distCenterToNorth = 10;
var distNorthToHeading = getDist(north, heading);
var distNorthToTarget = getDist(north, target);
*/
var angHeadingToTarget = getAngle(center, heading, target);
var angNorthToHeading = getAngle(center, north, heading);
var angNorthToTarget = getAngle(center, north, target);
if (((angNorthToHeading - angNorthToTarget) + 360) % 360 > 180) {
return angHeadingToTarget;
} else {
return -angHeadingToTarget;
}
}
function getAngle(Center, heading, target) {
var p12 = getDist(Center, heading);
var p13 = getDist(Center, target);
var p23 = getDist(heading, target);
return Math.acos((sq(p12) + sq(p13) - sq(p23)) / (2 * p12 * p13)) * 180 / Math.PI;
}
function point(iX, iY) {
var _X=iX;
var _Y=iY;
this.x = function () { return _X; };
this.y = function () { return _Y; };
this.setX = function (iX) {
_X = iX;
}
this.setY = function (iY) {
_Y = iY;
}
}
function getDist(p1, p2) { return Math.sqrt(Math.pow(p1.x() - p2.x(), 2) + Math.pow(p1.y() - p2.y(), 2)); }
function sq(num) { return Math.pow(num, 2); }
I will potentially need to get the rotation many times, and i've heard that the sqrt function is expensive... In the above example, it's being hit 9 times, where I can see that at least three of them are redundant (center to heading, center to target and center to north).
Is there a better way of doing this all-together?
Thanks in advance,
Dave
EDIT: #Mike Dunlavey
I've been messing around with atan2 but I cant seem to get anything that works. Maybe i'm just missing something simple, but could you explain? Thanks.
1) In your getDist function, it might be faster to just square the deltas, rather than calling Math.pow.
It's possible Math.pow treats integer powers as a special case, but in general it has to get wrapped up in log and exp, which you don't need.
2) To get the direction from one point to another, you can just use the Math.atan2 function.
No need to deal with distances.
I have these coordinate :
(45.463688, 9.18814)
(46.0438317, 9.75936230000002)
and I need (trought Google API V3, I think) to get the distance between those 2 points in metre. How can I do it?
If you're looking to use the v3 google maps API, here is a function to use:
Note: you must add &libraries=geometry to your script source
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry"></script>
<script>
var p1 = new google.maps.LatLng(45.463688, 9.18814);
var p2 = new google.maps.LatLng(46.0438317, 9.75936230000002);
alert(calcDistance(p1, p2));
//calculates distance between two points in km's
function calcDistance(p1, p2) {
return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}
</script>
I think you could do without any specific API, and calculate distance with plain Javascript:
This site has good info about geographical calculations and Javascript sample for distance calculation.
Ok, quick glance at Google API page and it seems, you could do it by:
Call DirectionsService().route() to get DirectionsResult with routes
For one or each route go through its legs property and calculate sum of distances
http://www.csgnetwork.com/gpsdistcalc.html
Has nothing to do with coding btw
EDIT
if you're looking for some code
Calculate distance between two points in google maps V3
This is primarily done with math outside of the google api, so you shouldn't need to use the API for anything other than finding the correct coordinates.
Knowing that, here's a link to a previously answered question relating to Javascript.
Calculate distance between 2 GPS coordinates
Try this
CLLocationCoordinate2D coord1;
coord1.latitude = 45.463688;
coord1.longitude = 9.18814;
CLLocation *loc1 = [[[CLLocation alloc] initWithLatitude:coord1.latitude longitude:coord1.longitude] autorelease];
CLLocationCoordinate2D coord2;
coord2.latitude = 46.0438317;
coord2.longitude = 9.75936230000002;
CLLocation *loc2 = [[[CLLocation alloc] initWithLatitude:46.0438317 longitude:9.75936230000002] autorelease];
CLLocationDistance d1 = [loc1 distanceFromLocation:loc2];
Try this:
const const toRadians = (val) => {
return val * Math.PI / 180;
}
const toDegrees = (val) => {
return val * 180 / Math.PI;
}
// Calculate a point winthin a circle
// circle ={center:LatLong, radius: number} // in metres
const pointInsideCircle = (point, circle) => {
let center = circle.center;
let distance = distanceBetween(point, center);
//alert(distance);
return distance < circle.radius;
};
const distanceBetween = (point1, point2) => {
//debugger;
var R = 6371e3; // metres
var φ1 = toRadians(point1.latitude);
var φ2 = toRadians(point2.latitude);
var Δφ = toRadians(point2.latitude - point1.latitude);
var Δλ = toRadians(point2.longitude - point1.longitude);
var a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
References: http://www.movable-type.co.uk/scripts/latlong.html
Are you referring to distance as in length of the entire path or you want to know only the displacement (straight line distance)? I see no one is pointing the difference between distance and displacement here. For distance calculate each route point given by JSON/XML data, as for displacement there is a built-in solution using Spherical class.
Are you referring to distance as in length of the entire path or you want to know only the displacement (straight line distance)? I see no one is pointing the difference between distance and displacement here. For distance calculate each route point given by JSON/XML data, as for displacement there is a built-in solution using Spherical class. The idea is if your are referring to distance then you just use the computeDistanceBetween on each path point and concatenate it.
//calculates distance between two points in km's
function calcDistance(p1, p2) {
return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}
What is the algorithm for storing the pixels in a spiral in JS?
http://www.mathematische-basteleien.de/spiral.htm
var Spiral = function(a) {
this.initialize(a);
}
Spiral.prototype = {
_a: 0.5,
constructor: Spiral,
initialize: function( a ) {
if (a != null) this._a = a;
},
/* specify the increment in radians */
points: function( rotations, increment ) {
var maxAngle = Math.PI * 2 * rotations;
var points = new Array();
for (var angle = 0; angle <= maxAngle; angle = angle + increment)
{
points.push( this._point( angle ) );
}
return points;
},
_point: function( t ) {
var x = this._a * t * Math.cos(t);
var y = this._a * t * Math.sin(t);
return { X: x, Y: y };
}
}
var spiral = new Spiral(0.3);
var points = spiral.points( 2, 0.01 );
plot(points);
Sample implementation at http://myweb.uiowa.edu/timv/spiral.htm
There are a couple of problems with this question. The first is that you're not really being specific about what you're doing.
1) Javascript isn't really a storage medium, unless you're looking to transmit the pixels using JSON, in which case you may want to rephrase to explicitly state that.
2) There's no mention of what you expect the spiral to look like - are we talking about a loose spiral or a tight spiral? Monocolor or a gradient or a series of colors ? Are you looking at a curved spiral or a rectangular one?
3) What is the final aim here? Are you looking to draw the spiral directly using JS or are you transmitting it to some other place?