Page 1 of 1

Angle of Incidence

Posted: Thu Jun 04, 2015 7:27 am
by Predz
Okay. This is less of scripting support and more of mathematical support :D

I have tried to work this out myself, but just MASSIVELY confused myself in the process. I want to calculate the angle of incidence upon a player shooting a wall. I am not worried whether this is a 2D or 3D angle, however must be calculated from the wall.

Picture below to explain a bit better.

Image

Posted: Thu Jun 04, 2015 7:45 am
by Ayuto
I guess you currently only have two points. The player's location and the impact location (which is on the wall). But I think you need another point on the wall, because you can't calculate the angle to a single point. :D

Posted: Thu Jun 04, 2015 8:10 am
by Predz
Couldn't we somehow obtain the vector of the wall though? Because if so then I have an idea ;)

EDIT: This is the problem I was having trouble with xD

Posted: Thu Jun 04, 2015 8:13 am
by necavi
Not easily. Maybe you should tell us what your end result is supposed to be?

Posted: Thu Jun 04, 2015 8:46 am
by Predz
I want to calculate the angle of incidence so I can bounce bullets off of walls :D

Posted: Thu Jun 04, 2015 9:14 am
by Rob123
Here's a sourcemod plugin which does something very similar to what you're after.
https://forums.alliedmods.net/showthread.php?t=152173

The key thing I think you are missing is the use of a 'normal' vector from the wall. This is a vector going 90 degrees out from the wall (perpendicular).

You can use this to manipulate your view vector and basically get the product of the two.

Good luck

Posted: Thu Jun 04, 2015 9:15 am
by Predz
Yeh the normal is exactly what I am after, however to find the normal you must get the vector of the wall :D

Posted: Thu Jun 04, 2015 9:26 am
by Rob123
Yea hopefully devs can weigh in with some equivalent of what sourcemod has: TR_GetPlaneNormal after using doing a traceray

Posted: Thu Jun 04, 2015 9:27 am
by Predz
Yeh I am working on something now. This plugin gave me an idea :D

Making a drawing for you guys now :D

Image

This requires 2 trace rays though.

Posted: Thu Jun 04, 2015 9:47 am
by Ayuto

Posted: Thu Jun 04, 2015 9:50 am
by Predz
Awesome!

However how would I obtain a vector from that? Or does it return the vector of the normal?

Posted: Thu Jun 04, 2015 9:57 am
by Ayuto
plane.normal returns a Vector object.

Sorry for the short answers. I'm currently in my phone.

Posted: Thu Jun 04, 2015 10:01 am
by Predz
No problem. Thanks, am currently testing this.

Posted: Thu Jun 04, 2015 11:21 am
by Predz
What I have so far, am a little stuck now. Any help would be appreciated :)

Also, think I went a little over the top with the math? Or is this all necessary?

A picture is underneath for your reference.

Syntax: Select all

view_vector = player.view_vector

# Construct the simple right angle triange including missing values.
triangle_point_c = wall_position - view_vector * 10
triangle_point_b = ray.end_position
triangle_point_a = None

# Obtain the normal of the trace ray. To find the final point.
# The vector is extended behind and infront to allow for the chance of the wall
# is on either side of the view_vector.
new_trace_vec = ray.plane.normal
new_trace_start_point = triangle_point_c - new_trace_vec * 100
new_trace_end_point = triangle_point_c + new_trace_vec * 100

# Create a trace ray for the normal, and use it to find point 'a'.
normal_ray = get_trace_ray(new_trace_start_point, new_trace_end_point)

if normal_ray.did_hit_world():
if normal_ray.end_position.get_distance(triangle_point_b) <= 100:
triangle_point_a = normal_ray.end_position

# If point 'a' was found.
if triangle_point_a:
# Find the length of A and B to determine the incidence angle.
triangle_length_A = triangle_point_c.get_distance(triangle_point_b)
triangle_length_B = triangle_point_c.get_distance(triangle_point_a)
incidence_angle = degrees(atan(triangle_length_B / triangle_length_A))
reflection_angle = 180 - incidence_angle

# Not create a triangle on the otherside to find the reflection vector.
triangle_vec_C = triangle_point_b - triangle_point_a
triangle_point_d = triangle_point_b + triangle_vec_C
triangle_length_C = triangle_point_a.get_distance(triangle_point_b)
triangle_length_D = triangle_length_C


Image

Posted: Thu Jun 04, 2015 10:32 pm
by Predz
Okay. Scrap everything I have been doing. I converted Rob123's suggested plugin directly and it works beautifully :grin:

Code is below :smile:

Syntax: Select all

from players.entity import PlayerEntity
from players.helpers import index_from_userid

from events import Event

from mathlib import Vector
from messages import SayText2

from effects import temp_entities

from filters.recipients import RecipientFilter

from engines.precache import Model

import random

beam_model = Model('sprites/laserbeam.vmt')

@Event
def weapon_fire(ev):
userid = ev.get_int('userid')
player = PlayerEntity(index_from_userid(userid))
origin = player.origin
angle = player.view_angle
velocity = player.view_vector
line = player.get_trace_ray()
normal = line.plane.normal
wall = line.end_position
product = normal.dot(velocity)
normal *= product*2
ricochet = velocity-normal
test = wall+ricochet*200
temp_entities.beam_points(
RecipientFilter(),
0,
wall,
test,
beam_model.index,
beam_model.index,
0,
255,
5,
3,
3,
3,
0,
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255),
255,
1
)