I'm having a mathematical issue that I can't get through.
I'm making a model browser in Lua where mouse movement is hooked to camera position, camera position has 2 modes: fixed and free, free works flawlessly whereas fixed seems to have issue with calculating proper Z.
X and Y is calculated properly and works without any issue, but Z seems to scale with X, Y way too much as seen here: http://puu.sh/oTN1v/5846343f82.webm (These camera warps happen whenever I click right mouse button, which happens even if I don't move mouse )
function self:RightMouseClick()
local cx, cy = mousepos()
local radius = math.sqrt( math.pow( campos.x, 2 ) + math.pow( campos.y, 2 ) )
local ang = ( camorigin - campos ):Angle()
function self:Think()
if input.IsMouseDown( MOUSE_RIGHT ) then
local x = camorigin.x + radius * math.cos( math.rad( 1 ) * ( 180 + ang.yaw + ( cx - mousex() ) * 0.5 ) )
local y = camorigin.y + radius * math.sin( math.rad( 1 ) * ( 180 + ang.yaw + ( cx - mousex() ) * 0.5 ) )
local z = camorigin.z + radius * math.sin( math.rad( 1 ) * ( ang.pitch + ( cy - mousey() ) * 0.5 ) )
campos = Vector( x, y, z )
end
end
end
#Edit: If you have no clue what this code means, you might aswell just tell me how to properly calculate Z for camera movement around axis
Removing camorigin from calculation of x, y, z worked out.
Related
I have an rendered Image. I want to apply radial and tangential distortion coefficients to my image that I got from opencv. Even though there is undistort function, there is no distort function. How can I distort my images with distortion coefficients?
I was also looking for the same type of functionality. I couldn't find it, so I implemented it myself. Here is the C++ code.
First, you need to normalize the image point using the focal length and centers
rpt(0) = (pt_x - cx) / fx
rpt(1) = (pt_y - cy) / fy
then distort the normalized image point
double x = rpt(0), y = rpt(1);
//determining the radial distortion
double r2 = x*x + y*y;
double icdist = 1 / (1 - ((D.at<double>(4) * r2 + D.at<double>(1))*r2 + D.at<double>(0))*r2);
//determining the tangential distortion
double deltaX = 2 * D.at<double>(2) * x*y + D.at<double>(3) * (r2 + 2 * x*x);
double deltaY = D.at<double>(2) * (r2 + 2 * y*y) + 2 * D.at<double>(3) * x*y;
x = (x + deltaX)*icdist;
y = (y + deltaY)*icdist;
then you can translate and scale the point using the center of projection and focal length:
x = x * fx + cx
y = y * fy + cy
I have this new efficient raycasting code:
vectorX, vectorY = math.cos(r * math.pi/180), math.sin(r * math.pi/180)
wallDistanceX, wallDistanceY = v[3] - v[1], v[4] - v[2]
wallParallelX, wallParallelY = -wallDistanceY, wallDistanceX
rayX, rayY = v[1] - cam.x, v[2] - cam.y
Distance = (
(rayX * wallParallelX) + (rayY * wallParallelY))/(
(vectorX * wallParallelX) + (vectorY * wallParallelY)
)
if (
(math.min(v[1],v[3]) <= (cam.x + (Distance * vectorX)) and math.max(v[1],v[3]) >= (cam.x + (Distance * vectorX))) and
(math.min(v[2],v[4]) <= (cam.y + (Distance * vectorY)) and math.max(v[2],v[4]) >= (cam.y + (Distance * vectorY)))
) then
table.insert(possibles, Distance)
else
table.insert(possibles, 0)
end
This segment of code was converted to Lua from the answer of this post, but when the rays are drawn, they look broken up, like this:
I've done my debugging and so, and it turns out that when the ray is tested for intersection of a line, a distance of 0 is returned (a distance of 0 being returned means that the ray supposedly didn't intersect with a wall). There is a wall present as you see, and the minimap in the top-left corner shows just that.
Any ideas on why the ray is not being detected when it intersects? If you don't understand something pleeease ask.
r = angle for ray
v = an index of the list {}; v[i] is either the x1,y1,x2,y2 of the line
I want to calculate a 3D position using lua, there's some built in functions and I have code to move the player forwards, but I want to move the player backwards.
local x, y, z = getElementPosition ( localPlayer )
local r = getPedRotation ( localPlayer )
x = x - math.sin ( math.rad ( r ) ) * 1.5
y = y + math.cos ( math.rad ( r ) ) * 1.5
setElementPosition ( localPlayer, x, y, z )
setElementRotation ( localPlayer, 0, 0, r )
To explain the above, getElementPosition returns 3 values, x, y and z... getPedRotation returns one, the rotation of the ped (in this case the player) and localPlayer is the player, the rest is pretty clear, setElementPosition sets the players position, same for rotation...
So in my mind the following should work to make the player move back
local x, y, z = getElementPosition ( localPlayer )
local r = getPedRotation ( localPlayer )
x = x + math.sin ( math.rad ( r ) ) * 1.5
y = y - math.cos ( math.rad ( r ) ) * 1.5
setElementPosition ( localPlayer, x, y, z )
setElementRotation ( localPlayer, 0, 0, r )
It doesn't work unfortunately, and no matter if I add/subtract 180ยบ to "r" it still does the same, the script is for MTA San Andreas, so if anyone can see where I've went wrong would be nice of you to tell me, was never good at math, but learning lots by doing little things like this.
Thanks in advance.
I'm developing 2d space shooter with LOVE2D in Lua and as I'm not math and physics expert I got some questions with implementing steering behavior for enemies.
I finally managed to make enemy "seeking" for a player and it looks like:
Code that makes it work (formula is taken from this answer - https://stackoverflow.com/a/2561054/2117550):
function Enemy:seek ()
local dx = self.player.x - self.x - self.xvel
local dy = self.player.y - self.y - self.yvel
-- normalize
local len = math.sqrt(dx * dx + dy * dy)
dx, dy = dx / len, dy / len
return dx, dy
end
Then I use my seek function in update:
function Enemy:update (dt)
-- seeking acceleration
local dx, dy = self:seek()
-- what is the proper way of calculating enemies rotation?
-- self.rotation = math.atan2(dx, dy) + ANGLE_ACCELERATION * dt
-- update velocity
self.xvel = self.xvel + dx * MAX_SPEED * dt -- * math.cos(self.rotation) it's not needed anymore?
self.yvel = self.yvel + dy * MAX_SPEED * dt -- * math.sin(self.rotation) it's not needed anymore?
-- moving entity in camera
_.checkWorldBounds(self)
local futureX = self.x + self.xvel * dt
local futureY = self.y + self.yvel * dt
local nextX, nextY, collisions, len = self.world:move(self, futureX, futureY, self.collisionFilter)
self.x = nextX
self.y = nextY
self.xvel = self.xvel * 0.99
self.yvel = self.yvel * 0.99
end
So the only problem now is that enemy's rotation is not changing though the front of the spaceship should always look into player's side.
I tried with math.atan2(dx, dy) but it makes entity rotating constantly.
What is missing or what am I doing wrong?
I'm not looking for someone to code this for me (although it would be very nice) but some formula or piece of advice will be highly appreciated.
If you're interested the source code is available at - https://github.com/voronianski-on-games/asteroids-on-steroids-love2d
I can't tell you what is wrong with your code, but hopefully this will help you out.
-- these are the coordinates of the point to which your object should be facing
local playerx, playery = 100, 100
-- these are the current coordinates of the object that needs to have its facing changed
local shipx, shipy = 200, 200
-- the angle to which your object should be rotated is calculated
angle = math.atan2(playery - shipy, playerx - shipx)
Note that by using body:setAngle(angle) ('body' is your objects body) your objects will be instantly rotated to given angle. If you want them to rotate at certain pace you could use:
local currentAngle = body:getAngle()
local adjustedAngle
if currentAngle > angle then
adjustedAngle = currentAngle - rotationSpeed * dt
elseif currentAngle < angle then
adjustedAngle = currentAngle + rotationSpeed * dt
else
adjustedAngle = currentAngle
end
body:setAngle(adjustedAngle)
Also note that the 'front' of your ship/body/object is to the right along the x-axis. In other words the angle is calculated from the x-axis and 0 means that the object is facing right.
I managed to make points via the print function appear in a circle shape and animated it to go in a constant rotation with the circle variable. However my attempt to auto arrange the points into a 1/number of points segments of the circle to make them laid out evenly without inputting the angle of each one seems instead to make them go around far more than 360 degrees around the circle, as it feeds into itself.
For example for 5 points I'd want each circle in 1/5th of the 360 degrees with even space on each side, which should make a regular pentagon shape if you joined up the dots
function love.load() --Only run at startup
cycle = 0
points = 9 -- should work on any value
radius = 0.5
love.window.setMode(90, 90)
end
function love.update()
cycle = cycle + 0.05
if cycle >= 360 then
cycle = 0
--prevent huge values
end
end
function love.draw()
i = 0
while i < points do
x = radius * math.deg(math.sin(cycle + (360 * (i / points )) ) )
y = radius * math.deg(math.cos(cycle + (360 * (i / points )) ) )
--cycle to move and i + 1 / points to auto arrange
b = (i / points )
b = round(b, 2)
love.graphics.print( b , 33 + x, 33 + y)
i = i + 1
end
end
function round(num, idp) --rounding function for display
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
What currently happens:
In your loop, you're doing
x = radius * math.deg(math.sin(cycle + (360 * (i / points )) ) )
y = radius * math.deg(math.cos(cycle + (360 * (i / points )) ) )
whereas, you want to have:
b = i / points
local c = cycle + (360 * b) -- to lessen the computation cost
x = radius * math.sin( math.rad(c) )
y = radius * math.cos( math.rad(c) )
You just needed to convert that 360 to radians using the lua math.rad() function, as lua's math.sin(O) and math.cos() functions go by radians rather than degrees. the excalamation point have nothing to do with code and are just there to grab your attention to the problem.
x = math.deg(radius*math.sin(cycle + (!!!math.rad(360)!!! * (i / points )) ) )
y = math.deg(radius*math.cos(cycle + (!!!math.rad(360)!!! * (i / points )) ) )
You need to use cos for x and sin for y to get the right order:
x = radius * math.deg(math.cos(cycle + (360 * (i / points )) ) )
y = radius * math.deg(math.sin(cycle + (360 * (i / points )) ) )