I am making a collision system but the intersections of a partial circle are not working. There is a line that is going through the edge of the circle can anyone help?
I am using canvas as well.
This is so you can see the output
let world = {}
let cnvs, ctx, cnvs2, ctx2, cnvs3, ctx3;
let n;
function distance(x1, y1, x2, y2) {
// Calculating distance
return Math.sqrt(Math.pow(x2 - x1, 2) +
Math.pow(y2 - y1, 2) * 1.0);
}
function mod(x, y) {
let output = x;
while (output >= y) {
output -= y
}
return output
}
function intersecting(n, t, r, e) {
return intersect(n.x, n.y, t.x, t.y, r.x, r.y, e.x, e.y)
}
function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
// Check if none of the lines are of length 0
if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) {
return false
}
denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
// Lines are parallel
if (denominator === 0) {
return false
}
let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator
let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator
// is the intersection along the segments
if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
return false
}
// Return a object with the x and y coordinates of the intersection
let x = x1 + ua * (x2 - x1)
let y = y1 + ua * (y2 - y1)
return {
x,
y
}
}
function inteceptCircleLineSeg(circle, line, check2, noN) {
if (!n) n = 0
var a, b, c, d, u1, u2, ret, retP1, retP2, v1, v2;
v1 = {};
v2 = {};
v1.x = line.x2 - line.x;
v1.y = line.y2 - line.y;
v2.x = line.x - circle.x;
v2.y = line.y - circle.y;
b = (v1.x * v2.x + v1.y * v2.y);
c = 2 * (v1.x * v1.x + v1.y * v1.y);
b *= -2;
d = Math.sqrt(b * b - 2 * c * (v2.x * v2.x + v2.y * v2.y - circle.radius * circle.radius));
if (isNaN(d)) { // no intercept
return false;
}
u1 = (b - d) / c; // these represent the unit distance of point one and two on the line
u2 = (b + d) / c;
retP1 = {}; // return points
retP2 = {}
ret = []; // return array
if (u1 <= 1 && u1 >= 0) { // add point if on the line segment
retP1.x = line.x + v1.x * u1;
retP1.y = line.y + v1.y * u1;
ret[0] = retP1;
} else {
//if (!check2) world.drawBackup.push({type:'arc',x:line.x + v1.x * u1,y:line.y + v1.y * u1,radius:5,start:0,end:2*Math.PI,lineWidth:1})
}
if (u2 <= 1 && u2 >= 0) { // second add point if on the line segment
retP2.x = line.x + v1.x * u2;
retP2.y = line.y + v1.y * u2;
ret[ret.length] = retP2;
} else {
//if (!check2) world.drawBackup.push({type:'arc',x:line.x + v1.x * u2,y:line.y + v1.y * u2,radius:15,start:0,end:2*Math.PI,lineWidth:1})
}
if (ret.length === 0) {
return false;
}
if (!check2) {
if (mod(circle.end, 2 * Math.PI) !== circle.start) {
let partial = false;
for (let i = circle.end; i < circle.end + circle.start; i += 0.01) {
if (u1 <= 1 && u1 >= 0) {
if (inteceptCircleLineSeg({
radius: 1,
x: Math.cos(i) * circle.radius + circle.x,
y: Math.sin(i) * circle.radius + circle.y,
start: 0,
end: Math.PI
}, {
x: line.x,
y: line.y,
x2: retP1.x,
y2: retP1.y
}, true)) {
ret[0].x = line.x + v1.x * u2
ret[0].y = line.y + v1.y * u2
partial = true
let intersection = intersecting({
x: Math.cos(circle.end) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.end) * (circle.radius + 0.5) + circle.y
}, {
x: Math.cos(circle.start) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.start) * (circle.radius + 0.5) + circle.y
}, {
x: line.x,
y: line.y
}, {
x: ret[0].x,
y: ret[0].y
})
if (!intersection) {
return false
}
}
} else if (u2 <= 1 && u2 >= 0) {
if (inteceptCircleLineSeg({
radius: 1,
x: Math.cos(i) * circle.radius + circle.x,
y: Math.sin(i) * circle.radius + circle.y,
start: 0,
end: Math.PI
}, {
x: line.x,
y: line.y,
x2: retP2.x,
y2: retP2.y
}, true)) {
ret[0].x = line.x + v1.x * u1
ret[0].y = line.y + v1.y * u1
partial = true
let intersection = intersecting({
x: Math.cos(circle.end) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.end) * (circle.radius + 0.5) + circle.y
}, {
x: Math.cos(circle.start) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.start) * (circle.radius + 0.5) + circle.y
}, {
x: line.x,
y: line.y
}, {
x: ret[0].x,
y: ret[0].y
})
if (!intersection) {
return false
}
}
}
}
if (partial) {
if (circle.fill) {
let intersection = intersecting({
x: Math.cos(circle.end) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.end) * (circle.radius + 0.5) + circle.y
}, {
x: Math.cos(circle.start) * (circle.radius + 0.5) + circle.x,
y: Math.sin(circle.start) * (circle.radius + 0.5) + circle.y
}, {
x: line.x,
y: line.y
}, {
x: ret[0].x,
y: ret[0].y
})
if (intersection) {
ret[0].x = intersection.x
ret[0].y = intersection.y
}
}
}
}
}
return ret;
}
world.mouseX = 0;
world.mouseY = 0;
function addEvent(el, ev, func) {
el.addEventListener(ev, func, false)
}
function removeEvent(el, ev, func) {
el.removeEventListener(ev, func)
}
world.cubeList = [];
world.cubeNum = 0;
world.drawBackup = [];
world.GetMouseCoords = function(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
world.mouseX = posx * cnvs.width / document.documentElement.clientWidth
world.mouseY = posy * cnvs.height / document.documentElement.clientHeight
}
world.cube = function(x, y, z, texture) {
this.id = world.cubeNum;
this.x = cnvs.width / 2 + (x)
this.y = cnvs.height / 2 + (y)
this.texture = texture;
world.cubeList[world.cubeNum] = this;
world.cubeNum++
}
world.drawList = []
world.drawLength = 0;
world.setupDraw = function(info) {
ctx.lineWidth = info.lineWidth
if (info.type !== 'group') ctx.beginPath()
if (info.type === 'arc') {
ctx.arc(info.x, info.y, info.radius, info.start, info.end)
this.start = info.start;
this.end = info.end;
this.x = info.x;
this.y = info.y;
this.radius = info.radius;
} else if (info.type === 'line') {
ctx.moveTo(info.x, info.y)
ctx.lineTo(info.x2, info.y2)
this.x = info.x;
this.y = info.y;
this.x2 = info.x2;
this.y2 = info.y2;
} else if (info.type === 'group') {
let lineMoveTo = 1;
for (let i = 0; i < info.items.length; i++) {
let me = info.items[i];
if (lineMoveTo === 1) ctx.beginPath();
if (me.type === 'line') {
if (lineMoveTo === 1) {
ctx.moveTo(me.x, me.y)
} else {
ctx.lineTo(me.x, me.y)
}
} else if (me.type === 'arc') {
ctx.arc(me.x, me.y, me.radius, me.start, me.end)
} else if (me.type === 'closePath') {
ctx.closePath()
lineMoveTo = 1;
}
if (me.type !== 'closePath') lineMoveTo = 0;
}
this.items = info.items
}
if (info.type === 'arc') {
this.fill = info.fill
if (info.fill) ctx.fill()
}
ctx.stroke()
this.lineWidth = info.lineWidth;
this.id = world.drawLength;
this.type = info.type;
world.drawList[world.drawLength] = this;
world.drawLength++
}
world.drawCam = function(cam) {
n = 0
ctx.lineWidth = 1;
let xList = [];
let yList = [];
for (let i = cam.i; i < cam.i + 1; i += 0.01) {
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(cam.x, cam.y);
let raduis = 600;
let x = cam.x + Math.cos(i) * raduis
let y = cnvs.height / 2 + Math.sin(i) * raduis
let t = inteceptCircleLineSeg({
radius: 1,
x: world.mouseX,
y: world.mouseY,
start: 0,
end: Math.PI * 2,
fill: false
}, {
x: cam.x,
y: cam.y,
x2: x,
y2: y
}, true)
if (t) ctx.lineWidth = 4
for (let i2 = 0; i2 < world.drawList.length; i2++) {
let me = world.drawList[i2];
if (me.type === 'arc') {
let touching;
touching = inteceptCircleLineSeg({
radius: me.radius,
x: me.x,
y: me.y,
start: me.start,
end: me.end,
fill: me.fill
}, {
x: cam.x,
y: cam.y,
x2: x,
y2: y
})
if (touching) {
x = touching[0].x;
y = touching[0].y;
}
} else if (me.type === 'line') {
let touching;
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me.x,
y: me.y
}, {
x: me.x2,
y: me.y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
} else if (me.type === 'group') {
for (let i3 = 0; i3 < me.items.length; i3++) {
let me2 = me.items[i3];
if (me2.type === 'arc') {
let touching;
touching = inteceptCircleLineSeg({
radius: me2.radius,
x: me2.x,
y: me2.y,
start: me2.start,
end: me2.end,
fill: false
}, {
x: cam.x,
y: cam.y,
x2: x,
y2: y
})
if (touching) {
x = touching[0].x;
y = touching[0].y;
}
if (i3 + 1 < me.items.length) {
let me3 = me.items[i3 + 1];
if (me3.type !== 'closePath') {
let x2 = me3.x;
let y2 = me3.y;
if (me3.type === 'arc') {
x2 = me3.x + Math.cos(me3.start) * me3.radius;
y2 = me3.y + Math.sin(me3.start) * me3.radius;
}
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me2.x + me2.radius,
y: me2.y
}, {
x: x2,
y: y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
}
}
} else if (me2.type === 'line') {
if (i3 + 1 < me.items.length) {
let me3 = me.items[i3 + 1];
if (me3.type !== 'closePath') {
let touching;
let x2 = me3.x;
let y2 = me3.y;
if (me3.type === 'arc') {
x2 = me3.x + Math.cos(me3.start) * me3.radius;
y2 = me3.y + Math.sin(me3.start) * me3.radius;
}
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me2.x,
y: me2.y
}, {
x: x2,
y: y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
}
}
}
}
}
}
for (let i2 = 0; i2 < world.drawList.length; i2++) {
let me = world.drawList[i2];
if (me.type === 'line') {
let touching;
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me.x,
y: me.y
}, {
x: me.x2,
y: me.y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
} else if (me.type === 'group') {
for (let i3 = 0; i3 < me.items.length; i3++) {
let me2 = me.items[i3];
if (me2.type === 'arc') {
if (i3 + 1 < me.items.length) {
let me3 = me.items[i3 + 1];
if (me3.type !== 'closePath') {
let x2 = me3.x;
let y2 = me3.y;
if (me3.type === 'arc') {
x2 = me3.x + Math.cos(me3.start) * me3.radius;
y2 = me3.y + Math.sin(me3.start) * me3.radius;
}
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me2.x + me2.radius,
y: me2.y
}, {
x: x2,
y: y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
}
}
} else if (me2.type === 'line') {
if (i3 + 1 < me.items.length) {
let me3 = me.items[i3 + 1];
if (me3.type !== 'closePath') {
let touching;
let x2 = me3.x;
let y2 = me3.y;
if (me3.type === 'arc') {
x2 = me3.x + Math.cos(me3.start) * (me3.radius);
y2 = me3.y + Math.sin(me3.start) * (me3.radius);
}
touching = intersecting({
x: cam.x,
y: cam.y
}, {
x: x,
y: y
}, {
x: me2.x,
y: me2.y
}, {
x: x2,
y: y2
})
if (touching) {
x = touching.x;
y = touching.y;
}
}
}
}
}
}
}
ctx.lineTo(x, y);
ctx.stroke();
xList.push(x)
yList.push(y)
}
ctx2.beginPath();
ctx2.moveTo(xList[0], yList[0])
for (let i = 1; i < xList.length; i++) {
ctx2.lineTo(xList[i], yList[i])
}
ctx2.stroke();
while (world.drawBackup.length > 0) {
world.draw(world.drawBackup[0])
let drawBackup = [];
for (let i = 1; i < world.drawBackup.length; i++) {
drawBackup.push(world.drawBackup[i])
}
world.drawBackup = drawBackup;
}
}
world.cam = {}
world.draw = function(info) {
ctx.lineWidth = info.lineWidth
if (info.type !== 'group') ctx.beginPath()
if (info.type === 'arc') {
ctx.arc(info.x, info.y, info.radius, info.start, info.end)
} else if (info.type === 'line') {
ctx.moveTo(info.x, info.y)
ctx.lineTo(info.x2, info.y2)
} else if (info.type === 'group') {
let lineMoveTo = 1;
for (let i = 0; i < info.items.length; i++) {
let me = info.items[i];
if (lineMoveTo === 1) ctx.beginPath();
if (me.type === 'line') {
if (lineMoveTo === 1) {
ctx.moveTo(me.x, me.y)
} else {
ctx.lineTo(me.x, me.y)
}
} else if (me.type === 'arc') {
ctx.arc(me.x, me.y, me.radius, me.start, me.end)
} else if (me.type === 'closePath') {
ctx.closePath()
lineMoveTo = 1;
}
if (me.type !== 'closePath') lineMoveTo = 0;
}
}
if (info.type === 'arc') {
if (info.fill) ctx.fill()
}
ctx.stroke()
}
world.runDraw = function(i) {
ctx.clearRect(0, 0, cnvs.width, cnvs.height)
ctx2.clearRect(0, 0, cnvs.width, cnvs.height)
ctx3.clearRect(0, 0, cnvs.width, cnvs.height)
ctx.strokeStyle = "blue";
ctx.fillStyle = "blue";
ctx2.strokeStyle = "blue";
ctx2.fillStyle = "blue";
ctx3.strokeStyle = "blue";
ctx3.fillStyle = "blue";
for (let i2 = 0; i2 < world.drawList.length; i2++) {
world.draw(world.drawList[i2])
}
world.drawCam(world.cam)
}
function setup() {
new world.setupDraw({
type: 'arc',
x: cnvs.width / 2,
y: cnvs.height / 2,
radius: 500,
start: 0,
end: 2 * Math.PI,
lineWidth: 8,
fill: false
})
new world.setupDraw({
type: 'line',
x: cnvs.width / 2 + Math.sin(1) * 500,
y: cnvs.height / 2 + Math.cos(1) * 500,
x2: cnvs.width / 2 + Math.sin(5) * 500,
y2: cnvs.height / 2 + Math.cos(5) * 500,
lineWidth: 8
})
new world.setupDraw({
type: 'line',
x: cnvs.width / 2 + Math.sin(2) * 500,
y: cnvs.height / 2 + Math.cos(2) * 500,
x2: cnvs.width / 2 + Math.sin(4) * 500,
y2: cnvs.height / 2 + Math.cos(4) * 500,
lineWidth: 8
})
new world.setupDraw({
type: 'group',
lineWidth: 1,
items: [{
type: 'line',
x: cnvs.width / 2 - 200,
y: 0
}, {
type: 'line',
x: cnvs.width / 2 - 200,
y: cnvs.height
}, {
type: 'arc',
x: cnvs.width / 2 - 200,
y: cnvs.height / 2 - 200,
radius: 50,
start: 5,
end: 2 * Math.PI
}]
})
addEvent(cnvs, 'mousemove', function(e) {
world.GetMouseCoords(e)
//$('#output').text(world.mouseX)
})
addEvent(cnvs, 'mousedown', function(e) {
world.GetMouseCoords(e)
world.cam.x = world.mouseX
world.cam.y = world.mouseY
})
world.cam = {
i: 4,
x: (cnvs.width / 2),
y: (cnvs.height / 2)
}
run()
}
function run() {
world.runDraw(world.cam.i)
//world.cam.i+=0.01
setTimeout(() => {
run()
}, 1)
}
window.onload = async function() {
cnvs = document.getElementById("canvas");
cnvs2 = document.getElementById("canvas2");
cnvs3 = document.getElementById("canvas3");
cnvs.width = 1000;
cnvs.height = 1000;
cnvs.style.background = "black";
cnvs2.width = 1000;
cnvs2.height = 1000;
cnvs2.style.background = "black";
cnvs3.width = 1000;
cnvs3.height = 1000;
cnvs3.style.background = "black";
ctx = cnvs.getContext('2d')
ctx2 = cnvs2.getContext('2d')
ctx3 = cnvs3.getContext('2d')
setup()
resize()
window.addEventListener('resize', function(e) {
resize()
});
}
function resize() {
let w = document.documentElement.clientWidth;
let h = document.documentElement.clientHeight;
cnvs.style.position = 'absolute';
cnvs2.style.position = 'absolute';
cnvs3.style.position = 'absolute';
cnvs.style.top = '0px'
cnvs.style.left = '0px'
cnvs2.style.top = h + 'px'
cnvs2.style.left = '0px'
cnvs3.style.top = (h * 2) + 'px'
cnvs3.style.left = '0px'
cnvs.style.width = w + "px";
cnvs.style.height = h + "px";
cnvs2.style.width = w + "px";
cnvs2.style.height = h + "px";
cnvs3.style.width = w + "px";
cnvs3.style.height = h + "px";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
<canvas id="canvas3"></canvas>
<p id="output" style="position:absolute;top:700px;color:white;"></p>
New contributor
2TKTK1234567 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.