Processing to Processing.js, PVector array - intersection

I just wrote a code in Processing(with some help, because I'm a beginner!!) and it doesn't work in Processing.js any idea how I can fix this code.
the code is a diagram showing intersection between one moving line and four other fixed lines.
I really appreciate your prompt answers , I have a deadline in two days and I'm a real beginner!!!
PVector[] lineCoordinates = new PVector[5];
PVector mStart, mEnd;
void setup() {
PFont font;
font = loadFont("ArialNarrow-12.vlw");
textFont(font, 12);
size(600, 200);
lineCoordinates[0] = new PVector(width/5, height/5); // start
lineCoordinates[1] = new PVector(width-10, height-(height/3)); // line 1
lineCoordinates[2] = new PVector(width-(width/5)-10, height-(height/3)); // line 2
lineCoordinates[3] = new PVector(width-(2*(width/5))-10, height-(height/3)); // line 3
lineCoordinates[4] = new PVector(width-(3*(width/5))-10, height-(height/3)); // line 4
mStart = new PVector(width/5, height-(height/3));
mEnd = new PVector();
fill(0);
strokeWeight(1);
}
void draw() {
background(255);
fill(0);
text("The Eye", (width/5)-10,( height/5)-5);
text("Picture Plane", mouseX, mouseY);
text("Horizon Line", 5, height-(height/3)-5);
text("x", width-(2*(width/5))+40, height-(height/3));
text("x", width-(3*(width/5))+40, height-(height/3));
text("x", width-(width/5)+40, height-(height/3));
fill(255,0,0);
noStroke();
ellipse(width-(width/5)-10, height-(height/3),5,5);
ellipse(width-(2*(width/5))-10, height-(height/3),5,5);
ellipse(width-(3*(width/5))-10, height-(height/3),5,5);
ellipse(width-10, height-(height/3),5,5);
fill(0);
stroke(1);
line(0, height-(height/3), width, height-(height/3)); // Horizon Line
mEnd.set(mouseX, mouseY, 0);
line(mStart, mEnd);
for (int i=1; i<lineCoordinates.length; i++) {
line(lineCoordinates[0], lineCoordinates[i]);
PVector is = lineIntersection(lineCoordinates[0], lineCoordinates[i], mStart, mEnd);
if (is!=null) { ellipse(is.x, is.y, 5, 5); }
}
}
void line(PVector s, PVector e) {
line(s.x, s.y, e.x, e.y);
}
PVector lineIntersection(PVector p1, PVector p2, PVector p3, PVector p4)
{
PVector b = PVector.sub(p2, p1);
PVector d = PVector.sub(p4, p3);
float b_dot_d_perp = b.x * d.y - b.y * d.x;
if (b_dot_d_perp == 0) { return null; }
PVector c = PVector.sub(p3, p1);
float t = (c.x * d.y - c.y * d.x) / b_dot_d_perp;
if (t < 0 || t > 1) { return null; }
float u = (c.x * b.y - c.y * b.x) / b_dot_d_perp;
if (u < 0 || u > 1) { return null; }
return new PVector(p1.x+t*b.x, p1.y+t*b.y);
}

Start by adding the following at the bottom:
void mouseMoved() {
x = mouseX;
y = mouseY;
redraw();
}
and replacing mouseX and mouseY with the x y vars.
At least this makes "Picture Plane" follow the mouse...

Related

LibGDX Cut texture with an angle

Suppose I have a Texture and I want to split it in half on a line rotated with a given angle.
In result I expect to get two Texture objects with the corresponding halfs of the original texture. Would be very nice if it could be done with some kind of transformation/masking so that I wouldn't have to store copies of two new textures at runtime.
Is this even possible?
I tried to work around Gdx.gl.glSsisors() but couldn't make it work as it requires screen coords to be passed as parameters.
Also I tried to go with Pixmap but couldn't find anything that would indicate it's even possible.
This can be achieved by manually calculating two skewed quads and render those using a SpriteBatch.
Cutting a sprite along angle angle we get a directional vector representing the cut by
public void cut(float angle) {
Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);
if we also define the four corners for the UV Mapping of the Texture, along with the center and one vector la going d away from the center and lb going -d
Vector2 c = new Vector2(0.5f, 0.5f);
Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);
Vector2 tl = new Vector2(0, 1);
Vector2 tr = new Vector2(1, 1);
Vector2 bl = new Vector2(0, 0);
Vector2 br = new Vector2(1, 0);
we can then calculate the intersection of the cut
Vector2 i1 = new Vector2();
Vector2 i2 = new Vector2();
if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
else {
if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
}
At this point we know that one half of the cut will consist of vertices i1, i2 and two of tl, tr, bl and br, so if we sort them by angle away from the cut and then take the first 4 from i1 we get the vertices required to build the skewed quad:
Vector2[] vertexList = new Vector2[] {
tl, tr, bl, br, i1, i2
};
Array<VertexAngle> vas = new Array<>();
for (Vector2 v : vertexList) {
Vector2 vd = (new Vector2(v)).sub(c);
float a = d.angle(vd);
VertexAngle va = new VertexAngle();
va.v = v;
va.a = a;
vas.add(va);
}
vas.sort(new Comparator<VertexAngle>() {
#Override
public int compare(VertexAngle a, VertexAngle b) {
return Float.compare(a.a, b.a);
}
});
Array<Vector2> nv = new Array<>();
for (VertexAngle va : vas)
nv.add(va.v);
int index = nv.indexOf(i1, true);
The a float array containing the vertex data for the draw call can be constructed and rendered with a call to draw on SpriteBatch.
For example:
Full source code for the above example is:
package com.bornander.sandbox;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import java.util.Comparator;
public class SandboxGame extends ApplicationAdapter {
OrthographicCamera camera;
SpriteBatch batch;
Texture texture;
CutTexture cutTexture;
public static class CutTexture
{
public static class VertexAngle {
public Vector2 v;
public float a;
}
public static class CutHalf {
public float[] vertices = new float[4 * 5];
public void translate(float x, float y) {
for(int i = 0; i < vertices.length; i += 5) {
vertices[i + 0] += x;
vertices[i + 1] += y;
}
}
}
public Vector2 position = new Vector2();
public Vector2 driftDirection = new Vector2();
public float drift = 0.0f;
public Texture source;
public CutHalf halfA = new CutHalf();
public CutHalf halfB = new CutHalf();
public void cut(float angle) {
Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);
Vector2 c = new Vector2(0.5f, 0.5f);
driftDirection.set(d).rotate(90.0f);
Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);
Vector2 tl = new Vector2(0, 1);
Vector2 tr = new Vector2(1, 1);
Vector2 bl = new Vector2(0, 0);
Vector2 br = new Vector2(1, 0);
Vector2 i1 = new Vector2();
Vector2 i2 = new Vector2();
if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
else {
if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
}
Vector2[] vertexList = new Vector2[] {
tl, tr, bl, br, i1, i2
};
Array<VertexAngle> vas = new Array<>();
for (Vector2 v : vertexList) {
Vector2 vd = (new Vector2(v)).sub(c);
float a = d.angle(vd);
VertexAngle va = new VertexAngle();
va.v = v;
va.a = a;
vas.add(va);
}
vas.sort(new Comparator<VertexAngle>() {
#Override
public int compare(VertexAngle a, VertexAngle b) {
return Float.compare(a.a, b.a);
}
});
Array<Vector2> nv = new Array<>();
for (VertexAngle va : vas)
nv.add(va.v);
int index = nv.indexOf(i1, true);
int idx = 0;
int lastIndex = 0;
for(int j = 0; j < 4; ++j) {
lastIndex = (index + j) % nv.size;
Vector2 vertex = nv.get(lastIndex);
float width = source.getWidth();
float height = source.getWidth();
float fx2 = position.x + width * vertex.x - width / 2.0f;
float fy2 = position.y + height * vertex.y - height / 2.0f;
halfA.vertices[idx++] = fx2;
halfA.vertices[idx++] = fy2;
halfA.vertices[idx++] = Color.WHITE_FLOAT_BITS;
halfA.vertices[idx++] = vertex.x;
halfA.vertices[idx++] = 1.0f - vertex.y;
}
idx = 0;
for(int j = 0; j < 4; ++j) {
Vector2 vertex = nv.get((lastIndex + j) % nv.size);
float width = source.getWidth();
float height = source.getWidth();
float fx2 = position.x + width * vertex.x - width / 2.0f;
float fy2 = position.y + height * vertex.y - height / 2.0f;
halfB.vertices[idx++] = fx2;
halfB.vertices[idx++] = fy2;
halfB.vertices[idx++] = Color.WHITE_FLOAT_BITS;
halfB.vertices[idx++] = vertex.x;
halfB.vertices[idx++] = 1.0f - vertex.y;
}
}
public void render(SpriteBatch batch) {
float dx = driftDirection.x * drift;
float dy = driftDirection.y * drift;
halfA.translate(dx, dy);
halfB.translate(-dx, -dy);
batch.draw(source, halfA.vertices, 0, 20);
batch.draw(source, halfB.vertices, 0, 20);
halfA.translate(-dx, -dy);
halfB.translate(dx, dy);
}
}
#Override
public void create () {
float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth();
camera = new OrthographicCamera(800, 800 * aspectRatio);
camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f, 0.0f);
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("badlogic.jpg"));
Gdx.gl.glCullFace(0);
cutTexture = new CutTexture();
cutTexture.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f);
cutTexture.source = texture;
cutTexture.cut(0);
}
float[] cutAngles = new float[] { 0.0f, -22.5f, -45.0f, -12.0f, -75.0f, -90.0f};
int ai = 0;
#Override
public void render () {
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
{
cutTexture.drift = 0.0f;
cutTexture.cut(cutAngles[(ai++) % cutAngles.length]);
}
cutTexture.drift -= 64.0f * Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(0.6f, 0.6f, 1.0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glCullFace(GL20.GL_NONE);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
cutTexture.render(batch);
batch.end();
}
}

libgdx box2d friction joint not working

I am trying to make a simple example using the friction joints of box2d. I have created a circle that can be controlled with the mouse or arrow keys. There is also a box which is meant to be pushed with the circle. The problem is that when I push the box it keeps moving forever. I have added an auxiliary static box so I can join both boxes with a friction joint to simulate top-down friction. But it doesn't work. Here is the code.
public class MyGdxGame extends ApplicationAdapter {
Camera camera;
int windowWidth, windowHeight;
World physicsWorld;
Box2DDebugRenderer debugRenderer;
Body frictionerBox;
Body boxBody;
Body circleBody;
#Override
public void create () {
camera = new OrthographicCamera(2, 2);
Box2D.init();
physicsWorld = new World(new Vector2(0, 0), true);
debugRenderer = new Box2DDebugRenderer();
// frictioner box
BodyDef bDef = new BodyDef();
bDef.type = BodyDef.BodyType.StaticBody;
bDef.position.set(0, 0);
frictionerBox = physicsWorld.createBody(bDef);
PolygonShape fShape = new PolygonShape();
fShape.setAsBox(10, 10);
FixtureDef fixDef = new FixtureDef();
fixDef.shape = fShape;
fixDef.density = 1.f;
fixDef.friction = 1.f;
//Fixture fix =
frictionerBox.createFixture(fixDef);
// box
bDef = new BodyDef();
bDef.type = BodyDef.BodyType.DynamicBody;
bDef.position.set(0, 50);
boxBody = physicsWorld.createBody(bDef);
PolygonShape bShape = new PolygonShape();
bShape.setAsBox(25, 25);
fixDef = new FixtureDef();
fixDef.shape = bShape;
fixDef.density = 1.f;
fixDef.friction = 1.f;
boxBody.createFixture(fixDef);
// circle
BodyDef cDef = new BodyDef();
cDef.type = BodyDef.BodyType.DynamicBody;
cDef.position.set(20, 20);
circleBody = physicsWorld.createBody(cDef);
CircleShape cShape = new CircleShape();
cShape.setRadius(12);
fixDef = new FixtureDef();
fixDef.shape = cShape;
fixDef.density = 1.f;
circleBody.createFixture(fixDef);
FrictionJointDef frictionJointDef = new FrictionJointDef();
frictionJointDef.maxForce = 10;
frictionJointDef.maxTorque = 10;
frictionJointDef.initialize(frictionerBox, boxBody, new Vector2(0, 0));
physicsWorld.createJoint(frictionJointDef);
bShape.dispose();
cShape.dispose();
fShape.dispose();
}
#Override
public void render () {
handleInput();
physicsWorld.step(Gdx.graphics.getDeltaTime(), 6, 2);
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(physicsWorld, camera.combined);
}
#Override
public void resize(int width, int height)
{
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
windowWidth = width;
windowHeight = height;
System.out.println("resized");
}
private void handleInput()
{
final float ARROW_SPEED = 60.0f;
final float MAX_SPEED = 200.f;
final float MIN_SPEED = 20.f;
float vx, vy;
if(Gdx.input.isTouched() || Gdx.input.isButtonPressed(Input.Buttons.LEFT))
{
int tx = (Gdx.input.getX() - windowWidth/2);
int ty = -Gdx.input.getY() + windowHeight/2;
float cx = camera.position.x;
float cy = camera.position.y;
float px = circleBody.getPosition().x;
float py = circleBody.getPosition().y;
px = px - cx;
py = py - cy;
vx = tx - px;
vy = ty - py;
float speed = (float) Math.sqrt(vx*vx + vy*vy);
if( speed > MAX_SPEED )
{
vx = (vx/speed) * MAX_SPEED;
vy = (vy/speed) * MAX_SPEED;
}
if( speed > 0 && speed < MIN_SPEED )
{
vx = (vx/speed) * MIN_SPEED;
vy = (vy/speed) * MIN_SPEED;
}
}
else
{
vx = vy = 0;
if(Gdx.input.isKeyPressed(Input.Keys.W))
{
vy += 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.S))
{
vy -= 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.A))
{
vx -= 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.D))
{
vx += 1;
}
float speed = (float) Math.sqrt(vx*vx + vy*vy);
if(speed > 0.f)
{
vx = (vx/speed) * ARROW_SPEED;
vy = (vy/speed) * ARROW_SPEED;
}
}
circleBody.setLinearVelocity(vx, vy);
}
}
What am I doing wrong?
I figured it out. It seems that for the friction to be noticeable you have to set very high values to maxForce and maxTorque.
frictionJointDef.maxForce = 1000000;
frictionJointDef.maxTorque = 10000000;

Box2d working on dynamically created bodies

I'm trying to learn box2d but i've a problem. I have 3 bodies in my project, 3 lines actually. i'm trying to set each lines y coordinate to -7 when they arrive to y coordinate 14. my code for checking if they are over 14 is below:
for (int i = 0; i < groundsArray.size(); i++) {
Body body2 = groundsArray.get(i);
float x_deg;
x_deg = body2.getTransform().getPosition().x;
if (body2.getUserData().equals("grounds" + i) && body2.getTransform().getPosition().y > 14) {
body2.setTransform(x_deg, -7, 0);
}
}
How i create bodies :
public void createGrounds(int i) {
// for some random positions
int rnd = random.nextInt(10);
int constant = -20;
int new_y = i * 7;
int result_x1 = constant + rnd;
int result_x2 = result_x1 + 16;
BodyDef bodyDef = new BodyDef();
FixtureDef fixtureDef = new FixtureDef();
// GROUND LEFT
// body definition
bodyDef.type = BodyType.StaticBody;
bodyDef.position.set(0, 0);
// ground shape
ChainShape groundShape = new ChainShape();
groundShape.createChain(new Vector2[] { new Vector2(result_x1, -new_y),new Vector2(result_x2, -new_y) });
// fixture definition
fixtureDef.shape = groundShape;
fixtureDef.friction = 5f;
fixtureDef.restitution = 0;
grounds = world.createBody(bodyDef);
grounds.createFixture(fixtureDef);
grounds.setUserData("grounds" + i);
groundsArray.add(grounds);
groundShape.dispose();
}
How i call createGrounds() inside show():
for (int i = 0; i <= 2; i++) {
createGrounds(i);
}
How i update the world and positions inside render():
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
accelX = Gdx.input.getAccelerometerX();
Vector2 gravity = new Vector2(-accelX * 6, -60.81f);
world.setGravity(gravity);
world.step(TIMESTEP, VELOCITYITERATIONS, POSITIONITERATIONS);
batch.setProjectionMatrix(camera.combined);
batch.begin();
world.getBodies(tmpBodies);
for (Body body : tmpBodies) {
if (body.getUserData().equals(ballsprite)
&& body.getUserData() instanceof Sprite) {
Sprite sprite = (Sprite) body.getUserData();
sprite.setPosition(
body.getPosition().x - sprite.getWidth() / 2,
body.getPosition().y - sprite.getHeight() / 2);
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
sprite.draw(batch);
}
float x_deg;
float y_deg;
x_deg = body.getTransform().getPosition().x;
y_deg = body.getTransform().getPosition().y;
y_deg = y_deg + game_speed;
body.setTransform(x_deg, y_deg, 0);
}
// The part i couldn't solve
for (int i = 0; i < groundsArray.size(); i++) {
Body body2 = groundsArray.get(i);
float x_deg;
x_deg = body2.getTransform().getPosition().x;
if (body2.getUserData().equals("grounds" + i)
&& body2.getTransform().getPosition().y > 14) {
body2.setTransform(x_deg, -7, 0);
}
}
batch.end();
debugRenderer.render(world, camera.combined);
}
Maybe change your for cycle to this
for(int i = groundsArray.size(); i > 0; i--){}

Trying to create a circle with VBO's - LWJGL

Im trying to create a circle in LWJGL , using VBO's and VAO , and move it using an offset , but it seems one vertex is stuck in the center of the screen . I can't figure out how to move it to the new location . Any help is appreciated , thanks !
P.S : I have already tried debugging the program , but I can't locate the faulty vertex in my array
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
public class Test {
// Setup variables
private int WIDTH = 800;
private int HEIGHT = 600;
private String title = "Circle";
// Quad variables
private int vbo = 0; // Vertex Buffer Object
private int vao = 0; // Vertex Array Object
int SUBDIVISIONS = 100;
float[] vertex = new float[(SUBDIVISIONS + 1) * 4];
public Test() {
// Initialize
setupOpenGL();
setupQuad();
while (!Display.isCloseRequested()) {
loop();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public void setupOpenGL() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle(title);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(-1); // If error , exit program
}
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public void setupQuad() {
float r = 0.2f;
float x;
float y;
float offSetX = 0.3f;
float offSetY = 0.3f;
vertex[0] = (float) Math.sin(Math.PI*2*0/SUBDIVISIONS) * r + offSetX;
vertex[1] = (float) Math.cos(Math.PI*2*1/SUBDIVISIONS) * r + offSetY;
for (int i = 2; i < 360; i = i + 2) {
double angle = Math.PI * 2 * i / SUBDIVISIONS;
x = (float) Math.cos(angle) * r;
vertex[i] = x + offSetX;
}
for (int i = 3; i < 360; i = i + 2) {
double angle = Math.PI * 2 * i / SUBDIVISIONS;
y = (float) Math.sin(angle) * r;
vertex[i] = y + offSetY;
}
FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertex.length);
vertexBuffer.put(vertex);
vertexBuffer.flip();
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,vertexBuffer,GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
public void loop() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL30.glBindVertexArray(vao);
GL20.glEnableVertexAttribArray(0);
// Draw the vertices
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, 0, vertex.length / 2);
// Put everything back to default (deselect)
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public static void main(String[] args) {
new Test();
}
}
"I think I've found the problem . I was setting the positions of only 359 vertices out of 404 vertices (nr of subdivisions + 1 times 4) . It seems the rest of the vertices were stuck at 0,0 on the screen . Allowing both FOR statements to cycle up to 404 seems to solve the problem"

AS3 - bug in Rectangle.inflatePoint() - doesn't deal with negative coordinates well

this seems a bit nutty:
var r:Rectangle = new Rectangle();
trace("initial rect: " + r); // (x=0, y=0, w=0, h=0)
var p:Point = new Point(-5, -3); // (x=-5, y=-3)
trace("point: " + p);
r.inflatePoint(p);
trace("inflated rect: " + r); // (x=5, y=3, w=-10, h=-6)
i would expect the result to be (x=-5, y=-3, width=5, height=3).
here's an implementation that returns the expected result:
public static function inflateRectByPoint(r:Rectangle,p:Point):void
{
var d:Number;
d = p.x - r.x;
if (d < 0)
{
r.x += d;
r.width -= d;
}
else if (d > r.width)
{
r.width = d;
}
d = p.y - r.y;
if (d < 0)
{
r.y += d;
r.height -= d;
}
else if (d > r.height)
{
r.height = d;
}
}
You're misunderstanding what inflatePoint does.
It's the same as inflate (except taking a Point argument rather than two coordinates) - enlarges the rectangle in every direction.
new Rectangle(0, 0, 2, 5).inflatePoint(new Point(2, 2))
Results in a Rectangle from -2, -2 to 4, 7.
Putting in negative numbers shrinks the rectangle - until it gets smaller than 0, at which point it inverts, as expected.