Can wavefront OBJ files have per-object (or per-group) vertices? - wavefront

I have an object broken into many small parts. I could maintain a global list of vertices and figure out which belong to each small part, but it would be easier in my use case if I could index relatively.
IE, I specify that part 0 has 8 vertices, and face 0 of part 0 uses vertex 0, 3, 4 of that part.
Is there a way to do this in Wavefront OBJ files? It's a little unclear how Groups and Objects work.
For example, is the following legal?
o myObj1
v 3159.000000 203.000000 1959.000000 1.000000
v 3161.000000 203.000000 1959.000000 1.000000
v 3161.000000 203.000000 1961.000000 1.000000
v 3159.000000 203.000000 1961.000000 1.000000
v 3159.000000 205.000000 1959.000000 1.000000
v 3161.000000 205.000000 1959.000000 1.000000
v 3161.000000 205.000000 1961.000000 1.000000
v 3159.000000 205.000000 1961.000000 1.000000
f 1 4 5
f 4 5 8
f 2 3 6
f 3 6 7
f 1 2 3
f 1 3 4
f 5 6 7
f 5 7 8
f 1 2 5
f 2 5 6
f 4 3 8
f 3 8 7
o myObj2
v 3159.000000 203.000000 1961.000000 1.000000
v 3161.000000 203.000000 1961.000000 1.000000
v 3161.000000 203.000000 1963.000000 1.000000
v 3159.000000 203.000000 1963.000000 1.000000
v 3159.000000 205.000000 1961.000000 1.000000
v 3161.000000 205.000000 1961.000000 1.000000
v 3161.000000 205.000000 1963.000000 1.000000
v 3159.000000 205.000000 1963.000000 1.000000
f 1 4 5
f 4 5 8
f 2 3 6
f 3 6 7
f 1 2 3
f 1 3 4
f 5 6 7
f 5 7 8
f 1 2 5
f 2 5 6
f 4 3 8
f 3 8 7
And so on. (Assuming coordinates is the coordinates, of course)
EDIT: Wikipedia states:
OBJ files, due to their list structure, are able to reference vertices, normals, etc. either by their absolute position (1 represents the first defined vertex, N representing the Nth defined vertex), or by their relative position (-1 represents the latest defined vertex). However, not all software supports the latter approach, and conversely some software inherently writes only the latter form (due to the convenience of appending elements without needing to recalculate vertex offsets, etc.), leading to occasional incompatibilities.
So this...should work? It's unclear what the format would look like however. In any case, it fails to work properly in 3D Viewer.

A little late to the party :)
You could use the relative vertex position as stated in the wikipedia quote; it accesses the latest (not the last) defined vertex. If you replace both face lists by this:
f -8 -5 -4
f -5 -4 -1
f -7 -6 -3
f -6 -3 -2
f -8 -7 -6
f -8 -6 -5
f -4 -3 -2
f -4 -2 -1
f -8 -7 -4
f -7 -4 -3
f -5 -6 -1
f -6 -1 -2
It shows both cubes in 3D Viewer. So even though OBJ doesn't associate them with the object or group, they can be accessed "locally".
You could also choose to write the vertices per object in reverse, so the first vertex (written last) can be referred to as -1, the second as -2, etc.

Vertex numbering is contiguous throughout a single OBJ file, regardless of any kinds of grouping used. This translates to positive vertex numbering being absolute and not relative in any way, and negative vertex numbering being relative to the last defined vertex (but still including all defined vertices).
Ie. vertex definitions don't have grouping.
Points ("p" tag) can (probably?) have grouping, but are meant to be rendered as actual points, not part of a face.
tl;dr the closest you can get to what you were attempting is negative indices, but whether it loads correctly would depend on the program loading it

Related

Error with anova_test : contrasts can be applied only to factors with 2 or more levels

I'm trying to run a repeated measures ANOVA using the rstatix package but I'm experiencing an error that doesn't make sense to me.
My dataframe is this:
id Group Time startle
<fct> <fct> <fct> <dbl>
1 55 WT SGH S1_120db 5.24
2 102 WT SGH S2_120db 7.12
3 167 WT SGH S3_120db 9.64
4 226 WT SGH S4_120db 20.7
5 278 WT SGH S5_120db 15.4
6 345 WT SGH S6_120db 10.8
7 394 WT SGH S7_120db 15.1
8 456 WT SGH S8_120db 9.52
9 508 WT SGH S9_120db 10.4
10 571 WT SGH S10_120db 12.8
And I would like to analyse differences of startle between Groups within Time. My ANOVA code is:
res5 <- anova_test(
data = maleP120,
dv = startle,
wid = id,
between = Group,
within = Time)
However, when I run this code I get this error:
Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) :
contrasts can be applied only to factors with 2 or more levels
I have looked it up but most people who ask about this error usually have NAs in their datasets or they only have one level in their factor variable(s). I can attest that I have no NAs and all of my factor variables have more than two level. If I run:
sapply(lapply(maleP120, unique), length)
I get this output:
id Group Time startle
754 3 13 719
I have no idea why this ANOVA isn't working. Any help would be much appreciated.

A simple mySQL query + Statistical Analysis

I'm looking for patterns in a database with around 1 million records. I've been experimenting a bit using Keras and TensorFlow, specifically LSTM,
However, as I'm really new in the field, on it, I found better results doing some very specific queries.
Having the following table with the following data:
round value class creacion
1 15.49 H 2018-01-27 14:03:54
2 7.42 H 2018-01-27 14:04:42
3 1.04 L 2018-01-27 14:39:28
4 2.71 H 2018-01-27 14:39:36
5 1.95 L 2018-01-27 14:39:59
6 4 H 2018-01-27 14:40:17
7 4.4 H 2018-01-27 14:40:45
8 1.52 L 2018-01-27 14:41:14
9 28.69 H 2018-01-27 14:41:28
10 7.44 H 2018-01-27 14:42:25
11 1.1 L 2018-01-27 14:43:02
12 1.1 L 2018-01-27 14:43:12
13 1.41 L 2018-01-27 14:43:21
14 1.04 L 2018-01-27 14:53:10
15 1.66 L 2018-01-27 14:53:19
16 8.44 H 2018-01-27 14:53:34
17 1.55 L 2018-01-27 14:54:13
18 2.39 H 2018-01-27 14:55:29
19 2.9 H 2018-01-27 14:55:50
20 1.66 L 2018-01-27 14:56:13
21 2.7 H 2018-01-27 14:56:29
22 7.53 H 2018-01-27 14:56:51
23 2.04 H 2018-01-27 14:57:28
24 1.97 L 2018-01-27 14:57:47
25 1.35 L 2018-01-27 14:58:05
As you can see, I'm classifying all values below 2, as 'L' (low) values, and bigger as H (high) values.
So the main goal here is trying to predict the next value.
I have been using this query, which sums 100 values, considering high values as 2 and low values as 1. The following query sums the last 100 results and provide one number as output, assuming that the number is lower than the median, we can predict that the chances of a high value are increased.
SELECT SUM(n)
FROM (
SELECT *, IF(value < 2, #nvalue := 1, #nvalue := 2) AS n
FROM crawler
ORDER BY round DESC
LIMIT 0, 100
) AS sub
So, the first question is about the query:
I would like to create a new column, adding the sum of the previous 100 values. Do you know how this could be done?
I can replicate the results doing the following query:
SELECT round, value, class, creacion, sum(n)
FROM (
SELECT *, if(value < 2, #nvalue := 1, #nvalue := 2) AS n
FROM crawler
ORDER BY round DESC
LIMIT 0, 100
) AS sub
However, it obviously displays the last record alone:
round value class creacion sum(n)
560894 3.24 hi 2018-06-22 22:58:59 162
When I'm actually looking for the same result, but with every single record with a limit to avoid the large loading times.
The naive way to get the last hundred values is:
select c.*,
(select sum(c2.value)
from (select c3.*
from c3
where c3.creation <= c.creation
order by c3.creation desc
limit 100
) c2
) as sum_last100
from crawler c;
Because the correlation clause is two levels deep, MySQL does not accept this.
In MySQL 8+, this is much easier:
select c.*,
sum(value) over (order by creation rows between 99 preceding and current row) as sum_last100
from crawler c;
At this point, I might suggest that you switch to either MySQL 8 or to some other database (such as Postgres). Getting your desired query to work efficiently on a million rows may not be worth the effort in older versions of MySQL.

Formatting JSON data in R

I'm really new to working with JSON data, so I had a question about formatting.
Here's the link to the data I was trying to work with
I was using JSONlite and did this:
shot<-"http://stats.nba.com/stats/playerdashptshotlog?DateFrom=&DateTo=&
GameSegment=&LastNGames=0&LeagueID=00&Location=&Month=0&OpponentTeamID=0&
Outcome=&Period=0&PlayerID=202322&Season=2014-15&SeasonSegment=&
SeasonType=Regular+Season&TeamID=0&VsConference=&VsDivision="
I then did fromJSON:
json_data <- fromJSON(paste(readLines(shot), collapse=""))
This gives me the data in a list. My issue (although for all I know I messed up working towards this) is trying to create a data frame out of this info. I was able to make a data frame with code I read under similar questions on the site, but it is all of the data in just one column. Any recommendations would be appreciated!
Thanks
Normally, first thing to do when you get a JSON, you look at the structure.
str(json_data)
Doing so will reveal that your data has a very simple structure: is is a dataframe with rows, a line of headers, wrapped in some metadata about what each column means. Using the $ will allow you to address those specific components. In other words, your specific json is already a data frame structure, all you gotta to is take it out of json
library(jsonlite)
json_data <- fromJSON(paste(readLines(shot), collapse=""))
str(json_data)
mydf <- data.frame(json_data$resultSets$rowSet)
colnames(mydf) <- unlist(json_data$resultSets$headers)
You ought to get something like this:
head(mydf)
GAME_ID MATCHUP LOCATION W FINAL_MARGIN SHOT_NUMBER PERIOD
1 0021401215 APR 14, 2015 - WAS # IND A L -4 1 1
2 0021401215 APR 14, 2015 - WAS # IND A L -4 2 1
3 0021401215 APR 14, 2015 - WAS # IND A L -4 3 1
4 0021401215 APR 14, 2015 - WAS # IND A L -4 4 1
5 0021401215 APR 14, 2015 - WAS # IND A L -4 5 1
6 0021401215 APR 14, 2015 - WAS # IND A L -4 6 1
GAME_CLOCK SHOT_CLOCK DRIBBLES TOUCH_TIME SHOT_DIST PTS_TYPE SHOT_RESULT
1 10:33 7.7 0 1 25 3 missed
2 8:41 14 10 9.6 10.7 2 made
3 6:42 14.9 11 9.7 18.2 2 missed
4 5:16 19 3 3.5 4.2 2 made
5 4:45 19.8 3 3.7 3.3 2 missed
6 3:08 13.5 10 9.7 18 2 missed
CLOSEST_DEFENDER CLOSEST_DEFENDER_PLAYER_ID CLOSE_DEF_DIST FGM PTS
1 Hill, George 201588 4.3 0 0
2 Hill, George 201588 5.7 1 2
3 Hill, George 201588 3 0 0
4 Miles, CJ 101139 4 1 2
5 Hill, Solomon 203524 3 0 0
6 Hill, George 201588 4.5 0 0

GNUPLOT: Joining different series of points with vectors

I have a file with data in 2 columns X and Y. There are some blocks and they are separated by a blank line. I want to join the points (given by their coordenates x and y in the file) in each block using vectors. I'm trying to use these functions:
prev_x = NaN
prev_y = NaN
dx(x) = (x_delta = x-prev_x, prev_x = ($0 > 0 ? x : 1/0), x_delta)
dy(y) = (y_delta = y-prev_y, prev_y = ($0 > 0 ? y : 1/0), y_delta)
which I've taken from Plot lines and vector in graphical gnuplot (first answer). The command to plot would be plot for[i=0:5] 'Field_lines.txt' every :::i::i u (prev_x):(prev_y):(dx($1)):(dy($2)) with vectors. The output is
and the problem is that the point (0,0) is being included even though it's not in the file. I don't think I understand what the functions dx and dy do exactly and how they are being used with the option using (prev_x):(prev_y):(dx($1)):(dy($2)) so an explanation of this would help me a lot to try to fix this.
This is the file:
#1
0 5
0 4
0 3
0.4 2
0.8 1
0.8 1
#2
2 5
2 4
2 3
2 2
2 1
2 0
#3
4 5
4.2 4
4.5 3
4.6 2
4.7 1
4.7 0
#4
7 5
7.2 4
7.5 3
7.9 2
7.9 1
7.9 0
#5
9 5
9 4
9.2 3
9.5 2
9.5 1
9.5 0
#6
11 7
12 6
13 5
13.3 4
13.5 3
13.5 2
13.6 1
14 0
Thanks!
I'm not completely sure, what the real problem is, but I think you cannot rely on the columns in the using statement to be evaluated from left to right, and your check $0 > 0 in the dx and dy some too late in my opinion.
I usually put all the assignments and conditionals in the first column, and that works fine also in your case:
set offsets 1,1,1,1
unset key
prev_x = prev_y = 1
plot for [i=0:5] 'Field_lines.txt' every :::i::i \
u (x_delta = prev_x-$1, prev_x=$1, y_delta=prev_y-$2, prev_y=$2, ($0 == 0 ? 1/0 : prev_x)):(prev_y):(x_delta):(y_delta) with vectors backhead
Also, to draw a vector from j-th row to the point in the following row you must invert the definition of x_delta and use backhead to draw the vectors in the correct direction

GNU Octave: How to find n maximum elements of a vector

I have vector in Octave like this:
[ 4 5 1 2 3 6 ]
Is there any function that returns n maximum elements of that vector, in this case, the three biggest are 6, 5, and 4?
[6 5 4]
The Octave max function only returns one maximum element. I want n maximum elements.
In GNU Octave, get the biggest n elements of a vector:
octave:2> X = [3 8 2 9 4]
octave:2> sort(X)
ans =
2 3 4 8 9
octave:8> sort(X)(end-2:end)
ans =
4 8 9
Description
What sort(X)(end-2:end) means is "sort the vector X, and give me the elements from 2 minus the end to the end, also known as the last 3 elements".
You can use the sort function for this.