Skip to content
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

Increase precision of dot bounds check in EGP:DrawPath #3184

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions lua/entities/gmod_wire_egp/lib/egplib/usefulfunctions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -348,31 +348,33 @@ function EGP:DrawPath( vertices, size, closed )
corners[#corners+1] = { r={x=x1-dir.y*size, y=y1+dir.x*size}, l={x=x1+dir.y*size, y=y1-dir.x*size} }
else
local dot = dir.x*lastdir.x + dir.y*lastdir.y
local scaling = size*math.tan(math.acos(dot)/2) -- complicated math, could be also be `size*sqrt(1-dot)/sqrt(dot+1)` (no idea what is faster)
if dot > 0.999 then -- also account for rounding errors, somehow the dot product can be >1, which makes scaling nan
if dot >= 1 then -- also account for rounding errors, somehow the dot product can be >1, which makes scaling nan
-- direction stays the same, no need for a corner, just skip this point, unless it is the last segment of a closed path (last segment of a open path is handled explicitly above)
if i == num+1 then
corners[#corners+1] = { r={x=x1-dir.y*size, y=y1+dir.x*size}, l={x=x1+dir.y*size, y=y1-dir.x*size} }
end
elseif dot < -0.999 then -- new direction is inverse, just add perpendicular nodes
elseif dot <= -1 then -- new direction is inverse, just add perpendicular nodes
corners[#corners+1] = { r={x=x1-dir.y*size, y=y1+dir.x*size}, l={x=x1+dir.y*size, y=y1-dir.x*size} }
elseif dir.x*-lastdir.y + dir.y*lastdir.x > 0 then -- right bend, checked by getting the dot product between dir and lastDir:rotate(90)
local offsetx = -lastdir.y*size-lastdir.x*scaling
local offsety = lastdir.x*size-lastdir.y*scaling
if dot < 0 then -- sharp corner, add two points to the outer edge to not have insanely long spikes
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1+(lastdir.x+lastdir.y)*size, y=y1+(lastdir.y-lastdir.x)*size} }
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1-(dir.x-dir.y)*size, y=y1-(dir.y+dir.x)*size} }
else
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1-offsetx, y=y1-offsety} }
end
else -- left bend
local offsetx = lastdir.y*size-lastdir.x*scaling
local offsety = -lastdir.x*size-lastdir.y*scaling
if dot < 0 then
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1+(lastdir.x-lastdir.y)*size, y=y1+(lastdir.y+lastdir.x)*size} }
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1-(dir.x+dir.y)*size, y=y1-(dir.y-dir.x)*size} }
else
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1-offsetx, y=y1-offsety} }
else
local scaling = size*math.tan(math.acos(dot)/2)
if dir.x*-lastdir.y + dir.y*lastdir.x > 0 then -- right bend, checked by getting the dot product between dir and lastDir:rotate(90)
local offsetx = -lastdir.y*size-lastdir.x*scaling
local offsety = lastdir.x*size-lastdir.y*scaling
if dot < 0 then -- sharp corner, add two points to the outer edge to not have insanely long spikes
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1+(lastdir.x+lastdir.y)*size, y=y1+(lastdir.y-lastdir.x)*size} }
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1-(dir.x-dir.y)*size, y=y1-(dir.y+dir.x)*size} }
else
corners[#corners+1] = { r={x=x1+offsetx, y=y1+offsety}, l={x=x1-offsetx, y=y1-offsety} }
end
else -- left bend
local offsetx = lastdir.y*size-lastdir.x*scaling
local offsety = -lastdir.x*size-lastdir.y*scaling
if dot < 0 then
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1+(lastdir.x-lastdir.y)*size, y=y1+(lastdir.y+lastdir.x)*size} }
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1-(dir.x+dir.y)*size, y=y1-(dir.y-dir.x)*size} }
else
corners[#corners+1] = { l={x=x1+offsetx, y=y1+offsety}, r={x=x1-offsetx, y=y1-offsety} }
end
end
end
end
Expand Down
Loading