Recovering elements of a Javascript Path2D - javascript

I want to examine the individual path segments of a Path2D object. For example, suppose that
path = new Path2D();
path.ellipse(70,90,2,2,0,0,2*Math.PI);
I want to pass path to some other function and pull out the elements of the Path2D so that they can be translated into another format. The big picture goal is to allow the user to create a path and translate it to TikZ for inclusion in a LaTeX document.
Is there something like Java's Shape.getPathIterator(), which allows one to examine each segment along a path. Can this be done Javascript? As a template, here is an outline of the Java code that does what I'm hoping to do in Javascript.
PathIterator p = path.getPathIterator(new AffineTransform());
while (p.isDone() == false)
{
double c = new double[6];
int t = p.currentSegment(c);
if (t == PathIterator.SEG_MOVETO)
// (c[0],c[1]) is the "move-to" point.
else if (t == PathIterator.SEG_LINETO)
// (c[0],c[1]) is the "line-to" point.
else if (t == == PathIterator.SEG_CUBICTO)
// c[0] through c[5] specify the cubic curve
else
// etc., etc.
}
Editing this after seeing #Kaiido's answer.
What I ended up doing was extending Path2D to a new class that is functionally identical, except that it stores each call to arc(), lineTo(), etc. to an array as the call is made. This allows me to examine the record of past calls. It may not be a sufficiently general solution for everyone, but it works for my needs.

No there is currently nothing in the API that allows us to do that.
There are some discussions to extend the Path2D API so it's less "opaque", but nothing tangible yet, I don't think anyone is actively working on it, and we can't be sure what it will include.
The current proposal reads
Path2D Inspection. Allow inspection of Path2D objects, that are currently opaque.
For what it's worth, I myself started working on this idea a few months ago, in the hope I could help this discussion get started somehow with a possible feature design.
My very ambitious idea is to bring an API like SVG's SVGPathData and add methods to Path2D like getBBox, getPathData(), setPathData(), toSVGString(), getTotalLength(), or getPointAtLength().
You can check this repository where lives my project, and below is a demo using your input.
const path = new Path2D();
path.ellipse(70,90,50,20,0,0,2*Math.PI);
const svgString = path.toSVGString();
document.querySelector("pre").textContent += svgString;
document.querySelector("path").setAttribute("d", svgString);
document.querySelector("canvas").getContext("2d").fill(path);
<script src="https://cdn.jsdelivr.net/gh/Kaiido/path2D-inspection#master/build/path2D-inspection.min.js"></script>
<pre>
const path = new Path2D();
path.ellipse(70,90,50,20,0,0,2*Math.PI);
path.toSVGString();
</pre>
SVG:<br>
<svg><path fill="green"></path></svg><br>
Canvas:<br>
<canvas></canvas>

Related

How to implement basic LOD mechanism on a 3D json asset

I am not able to implement LOD to a 3d Object with json data.
Here is my implementation:
loader.load('models/robot-threejs/robot.json', function(object){
var lod = new THREE.LOD(object);
for (var i=1; i<=3;i++) {
console.log("this"+i);
lod.addLevel(object,i);
}
lod.updateMatrix();
lod.matrixAutoUpdate = false;
// lod.updateMatrix();
// lod.matrixAutoUpdate = false;
scene.add(lod);
//scene.add(object);
// object.position.set(30, 30, 30);
})
You're implementing THREE.LOD wrong.
The constructor does not take any parameters, so when you do this: new THREE.LOD(object);, it does nothing. You just have to use new THREE.LOD();
You're adding the same mesh to LOD 3 times, so you're not gonna see any difference. You need to create separate meshes with different geometries if you want to see any change in detail. Keep in mind that you have to generate these geometries yourself. Three.js doesn't automatically change the geometry for you. But you could use the SimplifyModifier for this.
Not sure why you're playing with matrix updates. There's no reason for this here.
You also need to call lod.update(camera) on your render loop if you want to see the change in detail.
I strongly recommend you read the documentation for LOD and read through the code in this example to better understand how it works.

Box2dWeb call function when objects collide

I'm fairly new to javascript and box2d, i was wondering if someone knows how i can call a custom function when two objects collide. I tried using some examples that uses the b2ContactListener without any succes. I've placed an object above another and let the standard Box2d physics do it's thing.
I recieve two console outputs, the first is null and the second is Ball with the following code:
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact) {
console.log(contact.GetFixtureA().GetBody().GetUserData());
console.log(contact.GetFixtureB().GetBody().GetUserData());
};.
The two objects that need to collide are a b2_dynamicbody (ball) and a b2PolygonShape. (rectangle). Using bodyDef.userData = "Ball"; in my Ball.js and bodyDef.userData = "Mouse"; in my Mouse.js i try to identify if they are hit. Instead only the ball is displayed.
Next to that i'm sure this is not the correct way for detecting collision :P I hope i've explained it well enough, could somebody steer me in the right direction?
Ok I solved it myself, apparently I had to add my custom event to the world I create with box2d. So, the issue was solved by me reading big chunks of box2d documentation/manual which can be found here:
I started with adding a String as UserData() to every object which can collide and has to do something else next to just colliding. Using the following code:
bodyDef.userData = "Car";
note: every object has to have it's own unique string.
Then I created a new contact listener (formulated in my question above) and listened for fixtures colliding with each other. When that happens, I 'save' the fixtures UserData() in variables which I can then use to look what objects collide with each other.
var contactListener = new Box2D.Dynamics.b2ContactListener;
contactListener.BeginContact = function(contact) {
var fixA = contact.GetFixtureA().GetBody().GetUserData();
var fixB = contact.GetFixtureB().GetBody().GetUserData();
// if else statement here...
};
world.SetContactListener(contactListener);
Finally, I added the last statement world.SetContactListener(contactListener); to add the event to the world, making it possible for it to listen to collisions, which I forgot to add and thus was my problem.
Hope someone finds this usefull!

simplifying the contents of an input using the javascript math system

This obviuosly works perfectly:<script>alert(5*8-4)</script>
but i need to solve whatever someone puts inside an input box.
Heres what I thought of doing: I would get the value of the input, into a variable. then I would use
document.write("<script>alert("+theinputvalue+")<script>");
or do this:
var string="<script>alert("+theinputvalue+")<script>";document.write(string);
but nothing works.
Is it even possible to do this? if not, tell my what simple other system I could use.
eventually, I will use it to graph lines like this:
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d")
for(var x=-100; x<100; x=x+.2){
y = .1*(x*x)
ctx.fillRect(x+50, -1*y+50, 2, 2);
}
http://jsfiddle.net/KGgq4/
eval('5*8-4')
will result in 36
I'm not aware of any library that is doing that (this doesn't mean that there are no such it simply means I never actually needed that) but what you should end up doing is to build an automata that will parse input string and transform it to a proper graph with proper transformations. This is not very easy topic and if you want to go this route you should start reading on arithmetic expressions parsing algorithms (sorry I do not have any solution in place).
Or you can cheat and define types of equations that will be selected by user. Once user selects type of equation you should be able show user inputs where user will be able to select coefficients. You can read those coefficients into different variables and apply transformations in your draw procedure (For example if user will select type sin(x) you know that general equation has following formula: y = k*sin(a*x + b) + c. So once it is selected you can allow user to enter k, a, b, c and based on that input calculate appropriate locations of points for your graph.)
Well, third solution could involve "eval ", but usually you should avoid eval at any cost (B/c it is straight forward JavaScript injection which may be an OK for this case but may get you in trouble later in your life. ).
You can use math.js, which comes with an advanced expression parser. It supports definition of variables and functions.
// create an instance of math.js
var math = mathjs();
// evaluate an expression
math.eval('5*8-4'); // 36
// user defined function (returns a native JavaScript function)
var f = math.eval('f(x) = 2*x^2 + 6');
// use the function (for graphing or something)
f(2); // 14

Unittesting dependant tests

I've searched the site and some literature and couldn't get to a clear answer. I'm trying to learn unittesting while constructing a new webpage that simply works as a whiteboard to which you can add post-its.
I have a Canvas object which represents the whiteboard, and a ticket object to represent the post-its. I have (for now) global function to retrieve the one and only canvas, which i test like this:
this.testRetrieveCanvas = function()
{
var canvas = getCanvas();
this.assertTrue( canvas != null );
}
this.testCanvasType = function()
{
var canvas = getCanvas();
this.assertTrue( canvas instanceof Canvas );
}
this.testIfCanvasIsReused = function()
{
var canvas = getCanvas();
this.assertEquals( canvas, getCanvas() );
}
So, i test for three things:
Does the method return a canvas?
Is it an acutal canvas?
Does the method give me the same canvas always?
No problems so far. But a little later, i'm testing "adding the ticket to the canvas":
this.testAddTicketToCanvas = function()
{
var ticket = factory.createTicket("yellow");
var canvas = getCanvas();
canvas.addTicket( ticket );
this.assertTrue( canvas.contains( ticket ) );
};
As you can see, i'm using the getCanvas() function inside my test. Is this a dependent test now? I mean, the first three tests have to pass, if i want this test to be able to run without doubts. If it is dependent, how would i fix this?
Strictly speaking, you should override getCanvas() to return a preconstructed (i.e. the original constructor isn't called) partial mock of canvas. With that said, if canvas' constructor is an empty function and the getCanvas method has no business logic involved, you shouldn't have a problem.
I'd be more wary of the last two statements used together. canvas.addTicket( ticket ); is ok, since it's the function being tested. but then you're asserting that you have added the ticket using a method from the same object. What if this method isn't implemented yet, or returns false, or worse true? What if your addTicket method has secondary effects that could make it add the ticket to the list but change a flag that makes contains() throw an exception, or return false, or true? What if contains has certain business logic that makes it return false for the ticket your sending it, but true for the same ticket in production environment (i.e. your test ticket hasn't been properly initialized, is missing a state, has been marked as excluded from the environment's business flow), what if it has no logic now, but two months into the project the logic changes so that your test fails but all else works (a new state is added, and objects without this state are deemed non existant, except for clients a, b and c). I could go on.
My point is without the code we can't specifically answer your question, only give you pointers and general answers like the one above. If you really don't want to post code, then take into consideration all of these scenarios, and all the other scenarios you can think of, and if under these scenarios testing your code this way won't break code nor tests now and for the foreseeable future, then you're ok.
The short answer to your question is, no.
If your code does not violate any unit testing
principles as long as you adhere to these rules.
Usually, with those questions there is a huge discussion about mocking certain parts of your tests e.g. your getCanvas() function. I agree that there is reason behind this discussion and that if you want to proceed with testing or TDD in general you should dive deeper into this topic. (Please refer to this excellent article from Martin Fowler).
However, for the question if this is a valid unit test, I think it is not relevant as long as you adhere to the unit test rules.

Trying to move/animate a container in javascript using the easeljs library

I am trying to adapt the gamefromscratch page showing how to Handling sprite based shooting. But I'm trying to replace the sprite with a bitmap that's in a container. The point where I'm stumbling is the end of the onTick(delta) where there is a graphics object created , I don't know the syntax to replace
var g = new createjs.Graphics();
g.setStrokeStyle(5);
g.beginStroke(createjs.Graphics.getRGB(255,0,0));
g.drawCircle(this.x,this.y,10);
this.bulletGraphic = new createjs.Shape(g);
stage.addChild(this.bulletGraphic);
}
bullets.push(bullet);
with code that would work for a Bitmap In a container.
Thanks for looking .
I believe you are looking for g.beginBitmapStroke() to replace the g.drawCircle()
You can find the EaselJS Documentation here:
http://www.createjs.com/Docs/EaselJS/classes/Graphics.html#yui_3_8_0pr2_2_1363403850534_598
For just using a Bitmap instead of a Shape you could use:
this.bulletGraphic = new createjs.Bitmap('urlOrImage');
stage.addChild(this.bulletGraphic);
}
bullets.push(bullet);
if you want the bullet-Bitmap additionally to be in a container (for whatever reason):
this.bulletGraphic = new createjs.Container();
this.bulletBitmap = new createjs.Bitmap('urlOrImage');
this.bulletGraphic.addChild(this.bulletBitmap);
stage.addChild(this.bulletGraphic);
}
bullets.push(bullet);
A little sidenote from me (note related to your question, but in case you care):
The code-example given on that page explains the Math behind the topic pretty good, but code-wise I would not take this as a good example. For a bullet you would usually create a new class, inheriting from Shape or Bitmap, the author of this example uses a plain object and just references the graphical-asset (this.bulletGraphic) through it. So if you're just using this to learn the Math, this is good, if you want to take this to create a real game out of it, I'd suggest you to restructure the code quite a bit, because this will get messy very soon.

Categories