-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collide rotated rects #46
Comments
I'll have a more in depth look soon. Thank you for looking at this, it's absolutely something that's been on my radar, but... I'll offer some context for why this hasn't been included yet :) First is that the functionality is as you pointed out, achievable with collidePolyPoly. Although I'll be the first to admit it's rather complex for a beginner / without some extra work, which is why I'm considering it! Second is that it's maybe faster (maybe you could run some speed test comparisons on it?) to use the vector rotation to do the calculations. See some links to implementation ideas: #23. This potentially opens up a whole can of worms regarding refactoring everything, maybe to vectors for the basis of the library (inverting the logic that's happening now), which isn't bad, but is something to consider as it would be a considerable amount of work to add the feature into the core that way. Third is that to make this idea 'complete', Collide Rect Rotation is not the only feature that needs to be added before rotation overarchingly would be implemented. We'll need to add the ability for rotation in every piece of geometry which can rotate, so this means adding rotation capability for for anything with an ellipse, line, rectangle, or polygon. This is a big task and it would likely be more effective to implement something that looks at the internal rotate(), push(), pop(), translate() functions and acts accordingly. Ok, so that's all tough stuff, so lastly I want to say THANK YOU for writing this! It's something that many people have asked for and as you can see there are many considerations above that I just haven't had the time to work on yet. I'd love to hear your thoughts on the above points (I try to run these repos with as much community feedback before implementation or changing anything as possible – see closed issues) One thing that I think we should do immediately while working out an overarching plan for rotation would be to include this as an example in the live examples section of the readme / docs : #23 Do you think you'd be up for adapting your code above into an example instead of an implementation, at least in the short term? edit/addition: we now have a p5js editor account to house these examples and I'm happy to add examples to that account if you reply to this issue with one! |
Yes you are right. It will take a lot of time to make it possible to collide any rotated object. Maybe we should try bitmap collision? Like make second invisible canvas where it will draw objects inside push() pop() and use bitmap collision to collide them? Sorry if i suggested dumb idea, im not mega pro in p5.js ) |
that's certainly one option! I do wonder how its speed would be?.. I agree that it probably would be likely be the most seamless approach to make the library generally aware of the push() pop() translate() rotate() situation in a given project and just 'work' for those situations. I don't really even know where to begin with that! But having behavior which worked inside of that convention (which is very standard practice / used widely) would seem like a good place to put some effort. The bonus of this approach (I think?!) is also that it should be easily applied to the other collision circumstances with minimal code modification for each. |
I think for the start will be good to learn math and make code to work with rotations. You need to calculate object transformation when its rotated and then just collide like normal non rotated object. For example you have ellipse 200 200 30 50 and its rotated on PI / 3 in radians, you can use sin cos idk to calculate new x y dx and dy, and then just collide like normal ellipses. I think thats will be good choice from many variants. |
I think i found easy solution of 2 problems.
I upgraded code that i wrote before: /* Convert simple figures to polygons and collide them */
// get X rotation
p5.prototype.rotX = function rotX(x, y, a) {
return x * cos(a) - y * sin(a);
}
// get Y rotation
p5.prototype.rotY = function rotY(x, y, a) {
return x * sin(a) + y * cos(a);
}
// a - angle in radians
// convert rectangle to polygon, works with rectModes. You can use that to prevent rectMode(CENTER) or another mode issuse
p5.prototype.rectToPoly = function rectToPoly(x, y, w, h, a = 0) {
// Rect Mode: CENTER
if (this._renderer._rectMode == CENTER) {
return [
{ x: this.rotX(x - w / 2, y - h / 2, a), y: this.rotY(x - w / 2, y - h / 2, a) },
{ x: this.rotX(x - w / 2, y + h / 2, a), y: this.rotY(x - w / 2, y + h / 2, a) },
{ x: this.rotX(x + w / 2, y + h / 2, a), y: this.rotY(x + w / 2, y + h / 2, a) },
{ x: this.rotX(x + w / 2, y - h / 2, a), y: this.rotY(x + w / 2, y - h / 2, a) },
{ x: this.rotX(x - w / 2, y - h / 2, a), y: this.rotY(x - w / 2, y - h / 2, a) },
];
}
// Rect Mode: RADIUS
if (this._renderer._rectMode == RADIUS) {
return [
{ x: this.rotX(x - w, y - h, a), y: this.rotY(x - w, y - h, a) },
{ x: this.rotX(x - w, y + h, a), y: this.rotY(x - w, y + h, a) },
{ x: this.rotX(x + w, y + h, a), y: this.rotY(x + w, y + h, a) },
{ x: this.rotX(x + w, y - h, a), y: this.rotY(x + w, y - h, a) },
{ x: this.rotX(x - w, y - h, a), y: this.rotY(x - w, y - h, a) },
];
}
// Rect Mode: CORNER
return [
{ x: this.rotX(x, y, a), y: this.rotY(x, y, a) },
{ x: this.rotX(x, y + h, a), y: this.rotY(x, y + h, a) },
{ x: this.rotX(x + w, y + h, a), y: this.rotY(x + w, y + h, a) },
{ x: this.rotX(x + w, y, a), y: this.rotY(x + w, y, a) },
{ x: this.rotX(x, y, a), y: this.rotY(x, y, a) },
];
};
// convert ellipse to polygon, i will add ellipseMode support later. vc - how many vertexes polygon will has, 50 is default
p5.prototype.ellipseToPoly = function ellipseToPoly(x, y, xr, yr, a = 0, vc = 50) {
var ra = new Array(vc).fill();
for (var i = 0; i < vc; ++i) {
const rx = cos((TAU / vc) * i) * xr + x;
const ry = sin((TAU / vc) * i) * yr + y;
ra[i] = { x: this.rotX(rx, ry, a), y: this.rotY(rx, ry, a) };
}
ra[vc] = ra[0];
return ra;
}
// convert triangle to polygon
p5.prototype.triangleToPoly = function triangleToPoly(x1, y1, x2, y2, x3, y3, a = 0) {
return [
{ x: this.rotX(x1, y1, a), y: this.rotY(x1, y1, a) },
{ x: this.rotX(x2, y2, a), y: this.rotY(x2, y2, a) },
{ x: this.rotX(x3, y3, a), y: this.rotY(x3, y3, a) },
{ x: this.rotX(x1, y1, a), y: this.rotY(x1, y1, a) },
];
} Maybe this will help |
p5.collide2d.js lib can't collide rotated rects.
I'm suggesting to add this feature, bcs I lost much time to write it myself.
my version of code
The text was updated successfully, but these errors were encountered: