Alter the Math functions in Javascript - javascript

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.

Related

Javascript map() forEach() method not working in succession

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

Get angle Two lines svg react js

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

Understanding function

I am having trouble understanding a function hopefully someone can help me out here. I am trying to find the pitch diameter of a sprocket the function for this in JavaScript is:
function sprocket_diam(dataform,pitch,teeth)
{
var a,b,c,d,e;
a = pitch / 2;
b = teeth * 2;
c = 360 / b;
d = Math.sin ((c * Math.PI) / 180);
e = (a / d) * 2
dataform.diam.value = e;
}
The above function works just as intended but I am trying to do this by hand on a calculator. I think the problem I am having comes in the d variable. For example lets say I have a 15 tooth sprocket with a pitch of .5". Using the above formula the numbers for the variables I get are:
a=0.25,b=30,c=12, and for d I take (12*3.14)/180 which gives me 0.2093 so e=(0.25/.2093)*2 which ends up being 2.388915432 but is the incorrect answer it should be 2.404867172372066 Can someone point out what I am doing wrong? I have always struggled with math.
You didn't compute the sinus. (Math.sin)
Your error is that you do as if Math.PI would be 3.14.
If you use the precise value of Math.PI, you get 12*Math.PI/180 == 0.20943951023931953 instead of the 0.2093 you use and at the end you find 2.404867172372066

how to deal with brng.toRad is not a function

i am using toRad() function in javascript as below
var alpha1 = brng.toRad();
but when i run my code it gives an error saying "brng.toRad is not a function"
How does it work in java script, do i need to import some library???
You can also do this:
Number.prototype.toRad = function () { return this * Math.PI / 180; }
var oneeighty = 180;
console.log( oneeighty.toRad() ); // 180 degrees = Pi radians
Native javascript doesn't have a toRad function. Either
1) toRad was defined by google-maps somewhere and brng is just pointing to the wrong object (perhaps null?)
or
2) You need to define the method yourself
function toRad(degrees){
return degrees * Math.PI / 180;
}
toRad(180);

What is the algorithm for storing the pixels in a spiral in JS?

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?

Categories