Just horizontal and vertical:
8x8:
Optimal because 9 in one direction is impossible.
Horizontal, vertical, and +-1 slope diagonal:
8x4:
Discovered to be optimal using a SAT solver. In particular, 5x5 is impossible.
I proved optimality for the latter solution using a SAT solver. Here's the Rust code I used to generate the CNF file:
use std::env;
use std::fs::File;
use std::io::Write;
type Point = (usize, usize);
fn main() -> std::io::Result<()> {
let mut args = env::args();
let _ = args.next();
let x_size: usize = args.next().expect("X arg").parse().expect("X num");
let y_size: usize = args.next().expect("Y arg").parse().expect("Y num");
let filename = format!("grid-{}{}.cnf", x_size, y_size);
let mut file = File::create(&filename)?;
let points: Vec<Point> = (0..x_size)
.flat_map(|i| (0..y_size).map(move |j| (i, j)))
.collect();
let to_var = &|i, j| i + j * x_size + 1;
let mut count = 0;
for &(i, j) in &points {
for &(k, l) in &points {
if (i + k) % 2 == 0 && (j + l) % 2 == 0 && (i, j) < (k, l) {
if i == k || j == l || (j < l && k - i == l - j) || (j > l && k - i == j - l) {
count += 2;
}
}
}
}
writeln!(&mut file, "p cnf {} {}", x_size * y_size, count)?;
for &(i, j) in &points {
for &(k, l) in &points {
if (i + k) % 2 == 0 && (j + l) % 2 == 0 && (i, j) < (k, l) {
if i == k || j == l || (j < l && k - i == l - j) || (j > l && k - i == j - l) {
let mid1 = (i + k) / 2;
let mid2 = (j + l) / 2;
let v1 = to_var(i, j);
let v2 = to_var(mid1, mid2);
let v3 = to_var(k, l);
writeln!(&mut file, "{} {} {} 0", v1, v2, v3)?;
writeln!(&mut file, "-{} -{} -{} 0", v1, v2, v3)?;
}
}
}
}
println!("{}", filename);
Ok(())
}